莫凡Python学习笔记——PyTorch 动态神经网络(五):卷积神经网络

内容原文:https://morvanzhou.github.io/tutorials/machine-learning/torch/
一、什么是卷积神经网络CNN(深度学习)

卷积神经网络也近些年来逐步兴起的一种人工神经网络,因为利用卷积神经网络在图像和语音识别方面能够给出更好的预测结果,所以这一技术也被广泛的传播可利用。卷积神经网络最常被应用的方面是图像识别,不过现在在视频分析,自然语言处理,药物发现等等都有了比较多的应用,很火的Alpha Go,也是利用了卷积神经网络,让计算机看懂围棋。

卷积神经网络如何运作?
神经网络都是有一系列的神经层组成,每一层又存在很多神经元,我们的数据就是经过这一个个神经元的处理从而得到我们最后的结果的。
当输入数据是一张图片的时候,计算机看到的并不是一个个图像,而是一组数据,让计算机面对这样一组数据的时候,卷积神经网络便有了优势。
卷积?
卷积神经网络的卷积就是说,计算机在处理数据的时候并不是一个个像素点去处理,而是将图片分成一个个的小区域,让计算机去处理一个个区域,这样计算机就可以看到图像了,增强了计算机输入数据的连续性,同时增强了计算机对于整张图片的理解。
这里写图片描述
卷积神经网络有一个批量过滤器,持续不断的在图片上滚动收集图片的信息,每一次收集来的信息只是一小块像素区域,然后把收集来的信息进行整理,然后使信息有一个实际上的呈现,比如说计算机就可以看到图片的边缘信息,然后再以同样的步骤,用类似的批量过滤器扫过产生的这些边缘信息,神经网络利用这些边缘信息总结出更高层次的信息,比如,可利用这些边缘信息画图鼻子眼睛等轮廓,再经过一次过滤,脸部的信息也从这些边缘信息中总结出来,然后再把这些信息套入普通的全连接神经网络进行分类,这样就能得到输入的图片能够分为哪一类的结果了。
这里写图片描述

看上面这张图来理解图片的卷积,每个输入图片都有width,height,depth三个信息,其中depth是计算机呈现颜色的信息,如果是黑白图片的,那他的depth是1,如果是彩色图片那他的depth是3.
这里写图片描述
迭代器不断扫描,输出一个高度更高,宽和长更小的图片信息,然后再经过这样一次次的卷积,慢慢输出,更高更小的图片,就有了对输入图片更深的理解,加压缩的信息嵌入普通的神经层上,就能对图片进行分类了。
这里写图片描述

池化(pooling)
在每一次卷积的时候,神经层总是可能会无意的丢失一些信息,所以要利用pooling来解决这一问题。也就是说在卷积的时候,我们不压缩长宽,尽量保持更加完整的信息,保留更多的信息,而压缩的工作就交给池化。
池化其实是一个筛选过程,能将layer中有用的信息筛选出来,给下一层分析,同时也减轻了神经网络的计算负担和工作的准确有效性。
这里写图片描述
比较流行的一种方式就是这样,从下到上,先是输入图片(image),经过一层卷积层(convolution),然后在用池化(pooling)方式处理卷积的信息,这里使用的是max pooling的方式。然后再经过一次同样的处理,把得到的第二次处理的信息传入两层全连接的神经层(fully connected),这也是一般的两层神经网络层,最后在接上一个分类器(classifier)进行分类预测。

二、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

#Hyper Parameters
EPOCH = 1     #train the traning data n times, to save time, we just train 1 epoch
BATCH_SIZE = 50
LR = 0.001    #learning rate
DOWNLOAD_MNIST = False #如果你自己下载好了mnist数据了的话,将download设置成FALSE,如果还没有下载好数据的话,那就设置成TRUE    

train_data = torchvision.datasets.MNIST(
	root = './minst',
	train = True,    #if the train is True,the data downloaded is train data, however,it is test data. and test data is little than train data.
	transform=torchvision.transforms.ToTensor(),#改变数据类型(0,1),适合CNN输入
	download=DOWNLOAD_MNIST
)
print (train_data.train_data.size())
print (train_data.train_labels.size())
plt.imshow(train_data.train_data[0].numpy(),cmap='gray')
plt.title('%i' % train_data.train_labels[0])
plt.show()

train_loader = Data_DataLoader(datasets=train_data, batch_size=BATCH_SIZE,suffle=True,num_workers=2)
test_data = torchvision.datasets.MNIST(root='./mnist/',train=False)   #train=False  表示提取出来的是test_data
test_x = Variable(torch.unsqueeze(test_data.test_data, dim=1),volatile=True).type(torch.FloatTensor)[:2000]/255.   #提取测试数据并转换维度和格式,除以255,手动压缩到(0,1)
test_y = test_data.test_labels[:2000]  #都只是选取了钱2000个

#构建CNN网络
class CNN(nn.Module):
	def __init__(self):
		super(CNN,self).__init__()
		self.conv1 = nn.Sequential(
			nn.Conv2d(          #(1,28,28)
				in_channels=1,   #输入的数据的高度,这里用的是黑白图像所以是1,如果是彩色图像,那高度应该是3
				out_channels=16,    #输出的高度,也就是filter(过滤器)的个数,几个filter同时在一个区域进行扫描提取,然后将提取的信息放入下一层进行分析
				kernel_size=5,  #filter是5*5的大小
				stride=1,    #隔多少跳一下,步长,也就是每步跳多大间隔
				padding=2,   #为了防止当filter跳到每行的最后会有多余的部分,所以我们首先在图片的周围圈一圈0,使得整个扫描区域增大。if stride = 1,padding = (kernel_size-1)/2=(5-1)/2=2 
				
			),    #卷积层,只是一个有长宽高的过滤器,长宽表示获取信息的范围,高大概表示获取信息的量的意思吧。(16,28,28)
			nn.ReLU(),      #神经网络   (16,28,28)
			nn.MaxPool2d(kernel_size=2), #池化层,也就是用大小为2的pooling的手段,相当于把图片进行裁剪,成长宽更小但是高度不变的图片   (16,14,14)
		)  
		self.conv2 = nn.Sequential(
			nn.Conv2d(16,32,5,1,2),    #(32,14,14)
			nn.ReLU(),              #(32,14,14)
			nn.MaxPool2d(2)   #pooling 有两种,一种是最大的,一种是中值得,一般使用最大值的      (32,7,7)
	)
		self.out = nn.Linear(32 * 7 * 7, 10)   #这里需要二维的数据,但是上面conv2之后是三维的,所以需要将三维的数据展成二维的,在forWord来做
		
	 def forward(self, x):
		 x = self.conv1(x)          
		 x = self.conv2(x)            #(batch,32,7,7)考虑了batch
		 x = x.view(x.size(0),-1)      #扩展展平   (batch,32*7*7)
		 output = self.out(x)
		 return output, x
cnn = CNN()
print (cnn)
#定义优化器和损失函数
optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)
loss_func = nn.CrossEntropyLoss()
#训练
for epoch in range(EPOCH):
	for step, (x,y) in enumerate(train_loader):
		b_x = Variable(x)
		b_y = Variable(y)
		
		output = cnn(b_x)
		loss = loss_func(output, b_y)
		optimizer.zero_grad()
		loss.backward()
		optimizer.step()
		
		if step % 50 == 0:
			test_output = cnn(test_x)    #进行测试
			pred_y = torch.max(test_output, 1)[1].data.squeeze()    
			accuracy = sum(pred_y == test_y) / test_y.size(0)   
			print ('Epoch: ', epoch, '| train loss: %.4f' %loss.data[0], '| test accuracy: ')
test_output = cnn(test_x[:10])  #取前10个数据
pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze()
print(pred_y, 'prediction number')
print(test_y[:10].numpy(), 'real number')

这里写图片描述

发布了72 篇原创文章 · 获赞 21 · 访问量 8万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览