CNN卷积神经网络
import torch
import torch.nn as nn #为了简化,直接利用nn.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 training data n times,to save time,we just train 1 epoch
......
train_data=torchvision.datasets.MNIST( #MNIST是一个下载的代码,你可以去网上下载,下载到本地
root='./mnist', #将这个保存,保存到root里面,出来以后会自动出现图
train=Ture #因为是训练数据库,所以正确训练
transform=torchvision.transforms.ToTensor(), #将网上下载的数据(图片像素点的值)改成tensor的格式,压缩到(0,1),
download=DOWNLOAD_MINIST
只有在train-loadeder是压缩(0,1),所以在test——data中手动除以255#
class CNN(nn.Module):
def init(self):
super(CNN,self)._init_()
self.conv1=nn.Sequential(
nn.Conv2d( #就相当于过滤器f ilter,高度决定能提取多少特征值,长宽决定提取大小 ,可以想象将一张图片进行筛选,并筛选为更厚的一张图片。大小如果改变就是改变kernet扫描形式 #2d就是二维#(1,28,28)
in_channels=1 #输入厚度为1
out_channels=16 #输出厚度为16,16张图
kernet_size=5 #5*5的扫描形式
stride=1 #步长,从一个到下一个的跳度
padding=2 #在外面加多长的像素,计算结果一般是(kernal_size-1)/2
), #--->(16,28,28)
nn.ReLU(),#----->(16,28,28)
nn.MaxPool2d(kernel_size=2) #取这个filter里面最大(长宽)的进行,长宽改变,厚度不变 #---->(16,14,14)
)
self.conv2=nn.Sequential( #(16,14,14)
nn.Conn2d(16,32,5,1,2), #----》(32,14,14)
nn.ReLU(), #---->(32,14,14)
nn.MaxPoll2d(2) #(32,7,7)-----》三维数据
)
self.out=nn.Linear(3277,10) #前者指的是(32,7,7)是三维的而此处进行展平操作,后者指10个分类0~9
def forward(self,x):
x=self.conv1(x)
x=self.conv2(x) #(batch,32,7,7)
x=x.view(x.size(0),-1) #(batch,3277)批处理进行展平
output=self.out(x)
return output
cnn=CNN()
RNN?循环神经网络
可以用来将前面产生的结果保留下来进而对最后的结果产生影响,并且在将上一个RNN产生结果保留进行下一个结果输出的同时还能够使用新的数据与上一个一起作用,产生结果
LSTM RNN
为了解决普通RNN弊端提出的LSTM(长短期记忆)
RNN是有记忆,但有时也会健忘,因为梯度消失或梯度爆炸。梯度消失是指误差在反向传播的时候回逐渐减小,直至到开头的时候已经没有办法进行误差处理了,给了一个假消息。梯度爆炸是指,误差反向传播,等传到开头的时候误差会很大以至于超过处理范围。加入LSTM以后就相当于加入了一条主线剧情的线,输入是由主线剧情决定,主线剧情提取分线中重要的剧情保留,将反向传播的保留中,会将原来不需要的进行排除,再假如现在的新的数据。
RNN分类
RNN一般用于时间序列,用于图片,就是将时间的推进变为行数的推进,一个时间节点对应一行。
参数代码
BATCH_SIZE=64 #批训练的数量
TIME_SIZE=28 #每28步读取一行信息
INPUT_SIZE=28 #一行信息里有28个像素点
DOWNLOAD_MNIST=Ture #set to true if haven't download the data#
训练的搭建
train_data=dsets.MNIST(root='./mnist',train=Ture,transform=transforms.ToTensor(),download=DOWNLOAD_MNIST)
train_loader=torch.utils.Dtaloader(dataset=train_data,batch_size=BATCH_SIZE,shuffle=true) #可以一批批训练数据
测试搭建
test_data=dsets.MNIST(root='./mnist',train=False,transform=transform.ToTensor())#train=false意味着不训练,
test_x=Variable(test_data.test_data,volatile=True).type.FloatTensor)[:2000]/255. #0~255区间
test_y=test_data.test_labels.numpy().squeeze()[:2000] #2000担心吃不消
RNN架构
class RNN(nn.Module):
def _init_(self):
super(RNN,self)._init_()
self.rnn=nn.LSTM( #直接使用RNN准确率不高,所以此处使用LSTM#
input_size=INPUT_SIZE,
hidden_size=64,
num_layer=1, #RNN是一个个细胞元,这个决定了hidden_size的层数,越大越好,但是 速度慢
batch_firse=True,#顺序(batch,time_step,input_size)
)
self.out=nn.Linear(64,10) #接到神经层
def forward(self,x):
r_out,(h_c,h_n)=self.rnn(x,None) #x的shape(batch,time_step,input_size),根据input然后结合time_step=28进行,没进行一个time_step都从新再审视一下心的input=28。h_c&h_n指的是主线和副线,最后输出测试的是r_out
out=self.out(r_out[:,-1,:]) #上面那个有全部的,所以这里取最后一个
rnn=RNN()
print(rnn)
优化和损失的定义
optimizer=torch.optim.Adam(rnn.parameters(),lr=LR) #optimize all cnn parameters
loss_func=nn.CrossEntroLOSS()
for epoch in range(EPOCH):
for step,(x,y) in enumerate(train_loader): #gives batch data
b_x=Variable(x.view(-1,28,28)) #reshape x to (batch,time_step,input_size) 变成一个维度
b_y=Variable(y)
output = rnn(b_x) #输出。取最后一个数据的原因,是我们读完以后才开始做决定
loss=loss_funx(output,b_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if step%50==0:
test_output=rnn(test_x) #(samples,time_step,input_size)
pred_y=torch.max(test_output,1)[1].data.numpy().squeeze()
acuracy=sum(pred_y==test_y)/test_y.size
print('Epoch:',epoch,'|train loss:%.4f'%loss.data[0],'| test accuracy;%.2f') #每50步看一下训练误差和测试准确度
···
#前10个数据有无测试对
test_output=rnn(test_x[:10].view(-1,28,28))
pred_y=torch.max(test_output,1)[1].data.numpy().squeeze()
print(pred_y,'prediction number')
print(test_y[:10],'real numpy')
RNN回归
每一个时间节点都会输出,这是它的特点,这一次便能很好体现
class RNN(nn.Module):
def _init_(self):
super(RNN,self)._init_()
self.rnn=nn.RNN(
input_size=INPUT_SIZE, #1
hidden_size=32,
num_layer=1, #RNN是一个个细胞元,这个决定了hidden_size的层数,越大越好,但是 速度慢
batch_firse=True,#顺序,是不是第一个-->Yes,true。。(batch,time_step,input_size)
)
self.out=nn.Linear(32,1) #接到神经层.32个输入(接的是hidden_layer),1个输出(接的是num_layer)
def forward(self,x):
#x (batch,time_step,input_size)
#h_state (n_layers,batch,hidden_size)
#r_out (batch,time_step,output_size/hidden_size)
r_out,h_state=self.rnn(x,h_state) #h_state是记忆(最后一步的),input应当是记忆+新的输入
outs=[ ] #总的out存放处
for time_step in range(r_out.size(1)): #将上面每一个out经过time_step后取出来,过一下上面的nn.Linear。size(1)指的是r_out的维度
outs.append(self.out(r-out[:,time_step,:])) #每过一个time_step就取一个out存放到outs里面。
return torch.stack(outs,dim=1),h_state #由于outs是一个列表,所以将其转化成数组?,,,,h_state是等待下一次再输入的时候使用。
rnn=RNN()
print(rnn)
优化和损失的定义
optimizer=torch.optim.Adam(rnn.parameters(),lr=LR) #optimize all cnn parameters
loss_func=nn.MSELoss()
h_state=None #为了下面使用的时候更容易
for step in range(60): #取60步的数据点(以便拟合),然后将其放入x_np和y_np中去计算它们
x=Variavle(torch.from_numpy(x_np[np.newaxis,:,np.newaxis])) y=Variable(torch.from_numpy(x_np[np.newaxis,:,np.newaxis])) #将x和y包起来进行,后面那个就是维度,除time_step保留原来维度,其余皆变,shape(batch,time_step,input_size)
prediction,h_state=rnn(x,h_state)
h_state=Variable(h_state.data) #!! this step is important#将h-state包成一个包裹,以方便其改变的时候,可以进行更新
loss=loss_funx(output,b_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
非监督学习Autoencode
将图片进行打码,在还原。神经网络先压缩再解压
将图片进行数据压缩,可以得到精髓的部分(encode)用这个特征集代表我们所有的输入。如若想要还原数据,就需要解压,可以通过输入和输出的对比不断得到优化的网络。解压出来的部分不断优化,更像。
将一部分数据压缩解压进行学习。
AutoEncoder的类
class AuroEncoder(nn.Module):
def _init_(self):
super(AutoEncoder,self)._init_()
self.encoder=nn.Sequential( #gengkuai
nn.Linear(28*28,128) #像素点是28*28
nn.Tanh(),
nn.Linear(128,64),
nn.Tanh(),
nn.Linear(64,12),
nn.Linear(1,64),
nn.Tanh(),
nn.Linear(12,3)
)#这是一个不断压缩的过程,下面会解码解压缩
self.decoder=nn.nn.Sequential( #gengkuai
nn.Linear(3,12) #像素点是28*28
nn.Tanh(),
nn.Linear(12,64),
nn.Tanh(),
nn.Linear(64,128)
nn.Tanh(),
nn.Linear(128,28*28)
nn.Sigmoid(), #将输出值压缩到0~1范围,解码器
)
def forward(self,x):
encoded=self.encoder(x)
encoded=self.decoder(encoded)
return
autoencoder=AutoEncoder()
optimizer=torch.optim.Adam(rnn.parameters(),lr=LR) #optimize all cnn parameters
loss_func=nn.MSELoss()
for epoch in range(EPOCH):
for step,(x,y) in enumerate(train_loader): #gives batch data
b_x=Variable(x.view(-1,28,28)) #batch x,shape (batch,28*28)
b_y=Variable(x.view(-1,28,28)) #batch y,shape (batch,28*28)
b_label=Variable(y) #batch label
encoded,decoded=autoencoder(b_x)
loss=loss_funx(encoded,b_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if steo%100==0
DQN deep Q-learning network
if someday you find you need use the network, come 莫烦python。
GAN 生成对抗网络Generative Adversarial Nets
属于一种生成器,利用一种东西生成更多更好的东西
数据=/结果
无意义随机数--->good结果
(新手画家)Generator《---->随机数《-------->messy 画× 好√
↑ ↓ ↓
Discriminator(新手鉴赏家)
最终生成新的Generator,可将其用于其他很多方面
准备代码
import torch
import torch.nn as nn
from torch.autograd import Variable
import numpy as np
import matplotlib.pyplot as plt
torch.manual_seed(1) #reproducible可再生的
np.random.seed(1)
参数代码,生成名画和烂画
#超参数
BATCH_SIZE=64
LR_G=0.0001 #generator(生成器)学习效率
LR_D=0.0001 #discriminator(判断器)学习效率
N_IDEAS=5
ART_COMPONENTS=15 #线段上有15个点
PAINT_POINTS=np.vstack([np.linespce(-1,1,ART_COMPONENTS: for _in range(BATCH_SIZE))])#从-1~1的线段
名画,
def aretist_works():
a=np.random.uniform(1,2,size=BATCH_SIZE)[:,np.newaxis] #1~2区间,最后面是维度,随机生成画。
批处理。一个参数
paintings =a*np.power(PAINT_POINTS,2)+(a-1) #这就是我们的画,画进行的转变。生成的区间就是烂画和名画之间的区间
paintings=torch.from_numpy(painting).float()#tensor转化成numpy的形式
return Variable(paintings) #将其包起来
G=nn.Sequential( #一个随机灵感--->名画
nn.Linear(N_IDEAS,128)#前者为随机灵感,由上文知,其值为5
nn.ReLU(),
nn.Linear(128,ART_COMPONENTS), #最后生成的画/名画
)
D=nn.Sequential( #可接收名画也可接收随意一作家所画的画
nn.Linear(ART_COMPONENTS,128)
nn.ReLU(),
nn.Linear(128,1), #1判定是否为名画
nn.Sigmoid(),#转化成百分比的形式,有多少概率是著名画家所画的画
)
优化
opt_D=torchoptim.Adam(D.parameters(),lr=LR_D)
opt_G=torchoptim.Adam(G.parameters(),lr=LR_D)
学习
for step in range(10000):
artist_paintings=artist_works() #名画,随机的,但是是著名画家画的
G_idea=Variable(torch.randn(BATCH_SIZE,N_IDEAS))#生成随机数
G_paintings=G(G_ideas)
prob_artist0=D(artist_paintings)
prob_artist1=D(G_paintings) #不知道是新手还是著名画家画的,所以需要用这两个式子判别一下
D_loss=—torch.mean(torch.log(prob_artist0)+torch.log(1-prob_artist1)) #增加抽取到著名画家的画的可能性
G_loss=torch.log(1-prob_artist1)#想要增加自己被认为是著名画家的概率
opt_D.zero_grad()
D_loss.backward(retain_variable=True) #backward以后,我要保留一下之前网络参数,给下一次backward使用
opt_D.step()
opt_G.zero_grad()
G_loss.backward()
opt_G.step()
#####可视化的代码
不写了,就是有关plt,我不会写,到时看模板的。
##pytorch是动态的
#过拟合
自负=过拟合
方法:增加数据量;变用正规化;y=Wx,cost=(Wx-real y)^2+abs(W);y=Wx,cost=(Wx-real y)^2+(W)^2;
我们更喜欢它学到一个普遍的形式,所以过拟合不太好
##批标准化
网友评论