做门户网站的营业范围,知名网站设计服务商,建网站难吗?,石家庄视频优化公司一、CNN简介
1. 神经网络基础 输入层#xff08;Input layer#xff09;#xff0c;众多神经元#xff08;Neuron#xff09;接受大量非线形输入讯息。输入的讯息称为输入向量。 输出层#xff08;Output layer#xff09;#xff0c;讯息在神经元链接中传输、分析、权…一、CNN简介
1. 神经网络基础 输入层Input layer众多神经元Neuron接受大量非线形输入讯息。输入的讯息称为输入向量。 输出层Output layer讯息在神经元链接中传输、分析、权衡形成输出结果。输出的讯息称为输出向量。 隐藏层Hidden layer简称“隐层”是输入层和输出层之间众多神经元和链接组成的各个层面。如果有多个隐藏层则意味着多个激活函数。
2. 卷积一下哦
卷积神经网络Convolutional Neural NetworkCNN针对全连接网络的局限做出了修正加入了卷积层Convolution层和池化层Pooling层。通常情况下卷积神经网络由若干个卷积层Convolutional Layer、激活层Activation Layer、池化层Pooling Layer及全连接层Fully Connected Layer组成。
下面看怎么卷积的 1.如图可以看到
1两个神经元即depth2意味着有两个滤波器。 2数据窗口每次移动两个步长取3*3的局部数据即stride2。 3边缘填充zero-padding1主要为了防止遗漏边缘的像素信息。 然后分别以两个滤波器filter为轴滑动数组进行卷积计算得到两组不同的结果。
2.如果初看上图可能不一定能立马理解啥意思但结合上文的内容后理解这个动图已经不是很困难的事情
1左边是输入7*7*3中7*7代表图像的像素/长宽3代表R、G、B 三个颜色通道 2中间部分是两个不同的滤波器Filter w0、Filter w1 3最右边则是两个不同的输出 4随着左边数据窗口的平移滑动滤波器Filter w0 / Filter w1对不同的局部数据进行卷积计算。
局部感知左边数据在变化每次滤波器都是针对某一局部的数据窗口进行卷积这就是所谓的CNN中的局部感知机制。打个比方滤波器就像一双眼睛人类视角有限一眼望去只能看到这世界的局部。如果一眼就看到全世界你会累死而且一下子接受全世界所有信息你大脑接收不过来。当然即便是看局部针对局部里的信息人类双眼也是有偏重、偏好的。比如看美女对脸、胸、腿是重点关注所以这3个输入的权重相对较大。 参数共享数据窗口滑动导致输入在变化但中间滤波器Filter w0的权重即每个神经元连接数据窗口的权重是固定不变的这个权重不变即所谓的CNN中的参数权重共享机制。
3卷积计算
图中最左边的三个输入矩阵就是我们的相当于输入d3时有三个通道图每个通道图都有一个属于自己通道的卷积核我们可以看到输出output的只有两个特征图意味着我们设置的输出的d2有几个输出通道就有几层卷积核比如图中就有FilterW0和FilterW1这意味着我们的卷积核数量就是输入d的个数乘以输出d的个数图中就是2*36个其中每一层通道图的计算与上文中提到的一层计算相同再把每一个通道输出的输出再加起来就是绿色的输出数字啦 举例
绿色输出的第一个特征图的第一个值
1通道x[ : :0] 1*11*0 1 0像素点省略
2通道x[ : :1] 1*01*(-1)2*0 -1
3通道x[ : :2] 2*0 0
b 1
输出1-1 0 1这个是b 1
绿色输出的第二个特征图的第一个值
1通道x[ : :0] 1*01*0 0 0像素点省略
2通道x[ : :1] 1*01*(-1)2*0 -1
3通道x[ : :2] 2*0 0
b 0
输出0-1 0 1这个是b 0
二、CNN实例代码
import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.utils.data as Data
import torchvision
import matplotlib.pyplot as plt
模型训练超参数设置构建训练数据如果你没有源数据那么DOWNLOAD_MNISTTrue
#Hyper prameters
EPOCH 2
BATCH_SIZE 50
LR 0.001
DOWNLOAD_MNIST Truetrain_data torchvision.datasets.MNIST(root ./mnist,train True,download DOWNLOAD_MNIST
)
数据下载后是不可以直接看的查看第一张图片数据
print(train_data.data.size())
print(train_data.targets.size())
print(train_data.data[0])
结果60000张图片数据维度都是28*28单通道 画一个图片显示出来
# 画一个图片显示出来
plt.imshow(train_data.data[0].numpy(),cmapgray)
plt.title(%i%train_data.targets[0])
plt.show()
结果 训练和测试数据准备数据导入
#训练和测试数据准备
train_loaderData.DataLoader(datasettrain_data, batch_sizeBATCH_SIZE, shuffleTrue)test_datatorchvision.datasets.MNIST(root./mnist,trainFalse,
)#这里只取前3千个数据吧差不多已经够用了然后将其归一化。
with torch.no_grad():test_xVariable(torch.unsqueeze(test_data.data, dim1)).type(torch.FloatTensor)[:3000]/255 test_ytest_data.targets[:3000]
注意这里的归一化在此模型中区别不大
构建CNN模型:
开始建立CNN网络
class CNN(nn.Module):def __init__(self):super(CNN,self).__init__()一般来说卷积网络包括以下内容1.卷积层2.神经网络3.池化层self.conv1nn.Sequential(nn.Conv2d( #-- (1,28,28)in_channels1, #传入的图片是几层的灰色为1层RGB为三层out_channels16, #输出的图片是几层kernel_size5, #代表扫描的区域点为5*5stride1, #就是每隔多少步跳一下padding2, #边框补全其计算公式kernel_size-1/2(5-1)/22), # 2d代表二维卷积 -- (16,28,28)nn.ReLU(), #非线性激活层nn.MaxPool2d(kernel_size2), #设定这里的扫描区域为2*2且取出该2*2中的最大值 -- (16,14,14))self.conv2nn.Sequential(nn.Conv2d( # -- (16,14,14)in_channels16, #这里的输入是上层的输出为16层out_channels32, #在这里我们需要将其输出为32层kernel_size5, #代表扫描的区域点为5*5stride1, #就是每隔多少步跳一下padding2, #边框补全其计算公式kernel_size-1/2(5-1)/2), # -- (32,14,14)nn.ReLU(),nn.MaxPool2d(kernel_size2), #设定这里的扫描区域为2*2且取出该2*2中的最大值 -- (32,7,7)这里是三维数据)self.outnn.Linear(32*7*7,10) #注意一下这里的数据是二维的数据def forward(self,x):xself.conv1(x)xself.conv2(x) #batch,32,7,7#然后接下来进行一下扩展展平的操作将三维数据转为二维的数据xx.view(x.size(0),-1) #(batch ,32 * 7 * 7)outputself.out(x)return output把模型实例化打印一下
cnnCNN()
print(cnn)
结果 开始训练
# 添加优化方法
optimizertorch.optim.Adam(cnn.parameters(),lrLR)
# 指定损失函数使用交叉信息熵
loss_fnnn.CrossEntropyLoss()
开始训练我们的模型哦step0
for epoch in range(EPOCH):#加载训练数据for step,data in enumerate(train_loader):x,ydata#分别得到训练数据的x和y的取值b_xVariable(x)b_yVariable(y)outputcnn(b_x) #调用模型预测lossloss_fn(output,b_y)#计算损失值optimizer.zero_grad() #每一次循环之前将梯度清零loss.backward() #反向传播optimizer.step() #梯度下降#每执行50次输出一下当前epoch、loss、accuracyif (step%500):#计算一下模型预测正确率test_outputcnn(test_x)y_predtorch.max(test_output,1)[1].data.squeeze()accuracysum(y_predtest_y).item()/test_y.size(0)print(now epoch : , epoch, | loss : %.4f % loss.item(), | accuracy : , accuracy)
打印十个测试集的结果test_outputcnn(test_x[:10])
y_predtorch.max(test_output,1)[1].data.squeeze() #选取最大可能的数值所在的位置
print(y_pred.tolist(),predecton Result)
print(test_y[:10].tolist(),Real Result)结果 卷积层维度变化
1输入1*28*28即1通道28*28维
2卷积层-0116*28*28即16个卷积核卷积核维度5*5步长1边缘填充2维度计算公式B (A 2*P - K) / S 1即282*2-5/1 1 28
3池化层池化层为2*2所以输出为16*14*14
4卷积层-0232*14*14即32卷积核其它同卷积层-01
5池化层池化层为2*2所以输出为32*7*7
6fc层由于输出为1*10即10个类别的概率那么首先对最后的池化层进行压缩为二维132*7*7然后全连接层维度32*7*710最后132*7*7*32*7*710