AI算法:卷积神经网络CNN原理与实现

2023-02-07 0 460

1 演算法价值观

传递函数数学模型透过所结构设计的传递函数核与影像展开传递函数操作方式,抽取影像中的这类特点。透过传递函数应用层数的增进,抽取的特点从局部性到总体,进而对球体展开辨识。

2 演算法推论2.1 边沿特点检验实例

AI算法:卷积神经网络CNN原理与实现
关上腾讯新闻报道 查阅TNUMBERBX

图1. 影像边沿检验

倘若有两张影像,想让计算机系统弄清楚相片上有甚么球体,能做的事是检验影像的水准边沿与横向边沿。

(1)传递函数操作方式

如图1所示,是两个6*6的位图影像,内部结构两个3*3的行列式,在传递函数数学模型中,一般来说称作filter(冷却系统),对6*6的影像展开传递函数操作方式获得4*4的行列式。

AI算法:卷积神经网络CNN原理与实现
关上腾讯新闻报道 查阅TNUMBERBX

图2. 传递函数操作方式

如图2所示,3*3的filter与6*6的位图影像右上角3*3区域展开传递函数3*1+0*0+1*(-1)+1*1+5*0+8*(-1)+2*1+7*0+2*(-1)=-5,进而获得4*4右上角的-5。

(2)边沿抽取

AI算法:卷积神经网络CNN原理与实现
关上腾讯新闻报道 查阅TNUMBERBX

图3. 横向边沿抽取

为甚么这种传递函数操作方式能获得影像的边沿?

如图3所示,原图是6*6的位图影像,10的部分为亮地区,0的部分为暗地区。从10->0为横向边沿。用两个3*3的冷却系统,对影像展开传递函数操作方式,获得影像中间亮,两边暗。亮暗交接处为边沿。

(3)冷却系统类型

AI算法:卷积神经网络CNN原理与实现
关上腾讯新闻报道 查阅TNUMBERBX

图4. 横向冷却系统与水准冷却系统

​透过图4的横向冷却系统与水准冷却系统可同时实现横向边沿与水准边沿检验。

AI算法:卷积神经网络CNN原理与实现
关上腾讯新闻报道 查阅TNUMBERBX

图5. 冷却系统类型

​图5列出了一些常用的冷却系统,如sobel算子,scharr算子等。在传递函数数学模型中,把这些冷却系统当成我们要学习的参数,传递函数网络训练的目标就是去理解冷却系统的参数。

2.2 边沿填充padding

AI算法:卷积神经网络CNN原理与实现
关上腾讯新闻报道 查阅TNUMBERBX

图6. padding示意图

(1)为甚么展开padding?

按照上述的描述,相片每经过一次传递函数运算,会存在以下两个问题:

相片会缩小导致无法展开深层传递函数运算;原始相片边沿信息对输出贡献得少,输出相片丢失边沿信息。

(2)怎样展开padding?

假设输入的相片大小:

冷却系统的大小:

两个水准与横向边沿padding大小:

则经过传递函数操作方式的输出:

2.3 传递函数步长stride
AI算法:卷积神经网络CNN原理与实现
关上腾讯新闻报道 查阅精彩图片

图7. 传递函数步长为2

对于input=7*7,filter=3*3,stride=2,padding=0;经传递函数操作方式输出:;通用表示:, 表示向下取整。2.4 彩色影像的传递函数

以上讲述的传递函数都是位图影像的,如果想要在RGB影像上展开传递函数,冷却系统的大小不再是3*3,而是3*3*3,最后的3对应为通道数(channels)。传递函数生成影像中,每个位置的像素值,为3*3*3的冷却系统与影像相应位置相乘累加。如图8所示,冷却系统依次在RGB影像上滑动,最终生成的影像大小为4*4。

AI算法:卷积神经网络CNN原理与实现
关上腾讯新闻报道 查阅TNUMBERBX

图8. 单一filter彩色影像传递函数

​另外两个问题是,如果我们在不仅仅在影像总检验一种类型的特点,而是要同

AI算法:卷积神经网络CNN原理与实现
关上腾讯新闻报道 查阅TNUMBERBX

图9. 多个filter彩色影像传递函数

写成通用的形式:

输入维度:

每个滤波器的维度:

权重维度:

偏置维度:

输出维度:

其中:

2.5 池化层Pooling
AI算法:卷积神经网络CNN原理与实现
关上腾讯新闻报道 查阅TNUMBERBX

图10. Max pooling示意图

​在传递函数神经网络中,除了使用传递函数层外,还使用池化层来缩减模型大小,提高计算速度。池化层分为最大池化层(max pooling)与平均池化层(average pooling)。池化层中的max pooling是求每个冷却系统滑动地区内的最大值;average pooling是求每个冷却系统滑动地区内的平均值。

经过padding后的输出:

一般情况下padding=0,输出表示:

2.6 简单传递函数数学模型实例LeNet-5
AI算法:卷积神经网络CNN原理与实现
关上腾讯新闻报道 查阅TNUMBERBX

LeNet(LeNet-5)由两个传递函数层和三个全连接层构成。

这两传递函数层的传递函数核均为5*5,第两个传递函数层的输出通道为6,第二传递函数层的输出通道为16。每个池化层窗口的大小为2*2,步长为2。三个全连接层分别有120、84和10个输出。3 演算法同时实现

(1)下载数据集

import torchimport torch.nn as nnimport torch.nn.functional as Fimport torch.optim as optimfrom torchvision import datasets, transformsimport timefrom matplotlib import pyplot as pltpipline_train = transforms.Compose([#随机旋转相片transforms.RandomHorizontalFlip(),#將圖片尺寸resize到32x32transforms.Resize((32,32)),#將圖片轉化為Tensor格式transforms.ToTensor(),#正則化(當模型出現過擬合的情況時,用來降低模型的複雜度)transforms.Normalize((0.1307,),(0.3081,))pipline_test = transforms.Compose([#將圖片尺寸resize到32x32transforms.Resize((32,32)),transforms.ToTensor(),transforms.Normalize((0.1307,),(0.3081,))#下載数据集train_set = datasets.MNIST(root=”./data”, train=True, download=True, transform=pipline_train)test_set = datasets.MNIST(root=”./data”, train=False, download=True, transform=pipline_test)#載入数据集trainloader = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)testloader = torch.utils.data.DataLoader(test_set, Batch_size=32, shuffle=False)

(2)搭建LeNet-5网络结构,并确定前向传递过程

class LeNet(nn.Module):def __init__(self):super(LeNet, self).__init__()self.conv1 = nn.Conv2d(1, 6, 5)self.relu = nn.ReLU()self.maxpool1 = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(6, 16, 5)self.maxpool2 = nn.MaxPool2d(2, 2)self.fc1 = nn.Linear(16*5*5, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10)def forward(self, x):x = self.conv1(x)x = self.relu(x)x = self.maxpool1(x)x = self.conv2(x)x = self.maxpool2(x)x = x.view(-1, 16*5*5)x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)output = F.log_softmax(x, dim=1)return output

(3)将定义好的网络结构部署至CPU/GPU上,并定义优化器

#建立模型,部署gpu或cpudevice = torch.device(“cuda” if torch.cuda.is_available() else “cpu”)model = LeNet().to(device)#定义优化器optimizer = optim.Adam(model.parameters(), lr=0.001)

(4)定义训练过程

def train_runner(model, device, trainloader, optimizer, epoch):#訓練模型, 啟用 BatchNormalization 和 Dropout, 將BatchNormalization和Dropout置為Truemodel.train()total = 0correct =0.0#enumerate迭代已載入的数据集for i, data in enumerate(trainloader, 0):inputs, labels = data#把模型部署到device上inputs, labels = inputs.to(device), labels.to(device)#初始化梯度optimizer.zero_grad()#儲存訓練結果outputs = model(inputs)#計算損失和#多分類情況一般来说使用cross_entropy(交叉熵損失函式), 而對於二分類問題, 一般来说使用sigmoidloss = F.cross_entropy(ou(0)correct += (predict == labels).sum().item()#反向傳播loss.backward()#更新参数optimizer.step()if i % 1000 == 0:#loss.item()表示當前loss的數值print(“Train Epoch{} \t Loss: {:.6f}, Accuracy: {:.6f}%”.format(epoch, loss.item(), 100*(correct/total)))Loss.append(loss.item())Accuracy.append(correct/total)return loss.item(), correct/total

(5)定义测试过程

def test_runner(model, device, testloader):#模型驗證, 必須要寫, 否則只要有輸入数据, 即使不訓練, 它也會改變權值model.eval()#統計模型正確率, 設定初始值correct = 0.0test_loss = 0.0total = 0#torch.no_grad將不會計算梯度, 也不會進行反向傳播with torch.no_grad():for data, label in testloader:data, label = data.to(device), label.to(device)output = model(data)test_loss += F.cross_entropy(output, label).item()predict = output.argmax(dim=1)#計算正確數量total += label.size(0)correct += (predict == label).sum().item()#計算損失值print(“test_avarage_loss: {:.6f}, accuracy: {:.6f}%”.format(test_loss/total, 100*(correct/total)))

(6)执行训练与测试

if __name__==”__main__”:epoch = 5Loss = []Accuracy = []for epoch in range(1, epoch + 1):print(“start_time”, time.strftime(%Y-%m-%d %H:%M:%S, time.localtime(time.time())))loss, acc = train_runner(model, device, trainloader, optimizer, epoch)Loss.append(loss)Accuracy.append(acc)test_runner(model, device, testloader)print(“end_time: “, time.strftime(%Y-%m-%d %H:%M:%S, time.localtime(time.time())), \n)print(model)torch.save(model, ./models/model-mnist.pth) #儲存模型print(Finished Training)plt.subplot(2, 1, 1)plt.plot(Loss)plt.title(Loss)plt.show()plt.subplot(2, 1, 2)plt.plot(Accuracy)plt.title(Accuracy)plt.show()

(7)保存网络模型

print(model)torch.save(model, ./models/model-mnist.pth) #儲存模型

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务