CNN卷積神經(jīng)網(wǎng)絡(luò)
import torch
import torch.nn as nn #為了簡(jiǎn)化挂绰,直接利用nn.nn來(lái)進(jìn)行構(gòu)建神經(jīng)層
from torch.autograd import Variable
import torch.utils.data as Data
import torchvision #一個(gè)庫(kù),里面包含了很多圖片和數(shù)據(jù)的
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是一個(gè)下載的代碼较坛,你可以去網(wǎng)上下載,下載到本地
root='./mnist', #將這個(gè)保存冲粤,保存到root里面,出來(lái)以后會(huì)自動(dòng)出現(xiàn)圖
train=Ture #因?yàn)槭怯?xùn)練數(shù)據(jù)庫(kù)亮隙,所以正確訓(xùn)練
transform=torchvision.transforms.ToTensor(), #將網(wǎng)上下載的數(shù)據(jù)(圖片像素點(diǎn)的值)改成tensor的格式,壓縮到(0危纫,1),
download=DOWNLOAD_MINIST
只有在train-loadeder是壓縮(0,1),所以在test——data中手動(dòng)除以255#
class CNN(nn.Module):
def init(self):
super(CNN,self)._init_()
self.conv1=nn.Sequential(
nn.Conv2d( #就相當(dāng)于過(guò)濾器f ilter乌庶,高度決定能提取多少特征值种蝶,長(zhǎng)寬決定提取大小 ,可以想象將一張圖片進(jìn)行篩選瞒大,并篩選為更厚的一張圖片蛤吓。大小如果改變就是改變kernet掃描形式 #2d就是二維#(1,28,28)
in_channels=1 #輸入厚度為1
out_channels=16 #輸出厚度為16,16張圖
kernet_size=5 #5*5的掃描形式
stride=1 #步長(zhǎng)糠赦,從一個(gè)到下一個(gè)的跳度
padding=2 #在外面加多長(zhǎng)的像素会傲,計(jì)算結(jié)果一般是(kernal_size-1)/2
), #--->(16,28,28)
nn.ReLU(),#----->(16,28,28)
nn.MaxPool2d(kernel_size=2) #取這個(gè)filter里面最大(長(zhǎng)寬)的進(jìn)行,長(zhǎng)寬改變拙泽,厚度不變 #---->(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)-----》三維數(shù)據(jù)
)
self.out=nn.Linear(3277,10) #前者指的是(32,7,7)是三維的而此處進(jìn)行展平操作淌山,后者指10個(gè)分類(lèi)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)批處理進(jìn)行展平
output=self.out(x)
return output
cnn=CNN()
RNN?循環(huán)神經(jīng)網(wǎng)絡(luò)
可以用來(lái)將前面產(chǎn)生的結(jié)果保留下來(lái)進(jìn)而對(duì)最后的結(jié)果產(chǎn)生影響,并且在將上一個(gè)RNN產(chǎn)生結(jié)果保留進(jìn)行下一個(gè)結(jié)果輸出的同時(shí)還能夠使用新的數(shù)據(jù)與上一個(gè)一起作用顾瞻,產(chǎn)生結(jié)果
LSTM RNN
為了解決普通RNN弊端提出的LSTM(長(zhǎng)短期記憶)
RNN是有記憶泼疑,但有時(shí)也會(huì)健忘,因?yàn)樘荻认Щ蛱荻缺ê苫纭L荻认侵刚`差在反向傳播的時(shí)候回逐漸減小退渗,直至到開(kāi)頭的時(shí)候已經(jīng)沒(méi)有辦法進(jìn)行誤差處理了,給了一個(gè)假消息蕴纳。梯度爆炸是指会油,誤差反向傳播,等傳到開(kāi)頭的時(shí)候誤差會(huì)很大以至于超過(guò)處理范圍古毛。加入LSTM以后就相當(dāng)于加入了一條主線劇情的線翻翩,輸入是由主線劇情決定都许,主線劇情提取分線中重要的劇情保留,將反向傳播的保留中嫂冻,會(huì)將原來(lái)不需要的進(jìn)行排除胶征,再假如現(xiàn)在的新的數(shù)據(jù)。
RNN分類(lèi)
RNN一般用于時(shí)間序列桨仿,用于圖片睛低,就是將時(shí)間的推進(jìn)變?yōu)樾袛?shù)的推進(jìn),一個(gè)時(shí)間節(jié)點(diǎn)對(duì)應(yīng)一行服傍。
參數(shù)代碼
BATCH_SIZE=64 #批訓(xùn)練的數(shù)量
TIME_SIZE=28 #每28步讀取一行信息
INPUT_SIZE=28 #一行信息里有28個(gè)像素點(diǎn)
DOWNLOAD_MNIST=Ture #set to true if haven't download the data#
訓(xùn)練的搭建
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) #可以一批批訓(xùn)練數(shù)據(jù)
測(cè)試搭建
test_data=dsets.MNIST(root='./mnist',train=False,transform=transform.ToTensor())#train=false意味著不訓(xùn)練钱雷,
test_x=Variable(test_data.test_data,volatile=True).type.FloatTensor)[:2000]/255. #0~255區(qū)間
test_y=test_data.test_labels.numpy().squeeze()[:2000] #2000擔(dān)心吃不消
RNN架構(gòu)
class RNN(nn.Module):
def _init_(self):
super(RNN,self)._init_()
self.rnn=nn.LSTM( #直接使用RNN準(zhǔn)確率不高,所以此處使用LSTM#
input_size=INPUT_SIZE,
hidden_size=64,
num_layer=1, #RNN是一個(gè)個(gè)細(xì)胞元伴嗡,這個(gè)決定了hidden_size的層數(shù)急波,越大越好从铲,但是 速度慢
batch_firse=True瘪校,#順序(batch,time_step,input_size)
)
self.out=nn.Linear(64,10) #接到神經(jīng)層
def forward(self,x):
r_out,(h_c,h_n)=self.rnn(x,None) #x的shape(batch,time_step,input_size),根據(jù)input然后結(jié)合time_step=28進(jìn)行,沒(méi)進(jìn)行一個(gè)time_step都從新再審視一下心的input=28名段。h_c&h_n指的是主線和副線阱扬,最后輸出測(cè)試的是r_out
out=self.out(r_out[:,-1,:]) #上面那個(gè)有全部的,所以這里取最后一個(gè)
rnn=RNN()
print(rnn)
優(yōu)化和損失的定義
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) 變成一個(gè)維度
b_y=Variable(y)
output = rnn(b_x) #輸出伸辟。取最后一個(gè)數(shù)據(jù)的原因麻惶,是我們讀完以后才開(kāi)始做決定
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步看一下訓(xùn)練誤差和測(cè)試準(zhǔn)確度
···
#前10個(gè)數(shù)據(jù)有無(wú)測(cè)試對(duì)
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回歸
每一個(gè)時(shí)間節(jié)點(diǎn)都會(huì)輸出信夫,這是它的特點(diǎn)窃蹋,這一次便能很好體現(xiàn)
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是一個(gè)個(gè)細(xì)胞元,這個(gè)決定了hidden_size的層數(shù)静稻,越大越好警没,但是 速度慢
batch_firse=True,#順序振湾,是不是第一個(gè)-->Yes,true杀迹。。(batch,time_step,input_size)
)
self.out=nn.Linear(32,1) #接到神經(jīng)層.32個(gè)輸入(接的是hidden_layer)押搪,1個(gè)輸出(接的是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應(yīng)當(dāng)是記憶+新的輸入
outs=[ ] #總的out存放處
for time_step in range(r_out.size(1)): #將上面每一個(gè)out經(jīng)過(guò)time_step后取出來(lái),過(guò)一下上面的nn.Linear大州。size(1)指的是r_out的維度
outs.append(self.out(r-out[:,time_step,:])) #每過(guò)一個(gè)time_step就取一個(gè)out存放到outs里面续语。
return torch.stack(outs,dim=1),h_state #由于outs是一個(gè)列表,所以將其轉(zhuǎn)化成數(shù)組厦画?绵载,,,娃豹,h_state是等待下一次再輸入的時(shí)候使用焚虱。
rnn=RNN()
print(rnn)
優(yōu)化和損失的定義
optimizer=torch.optim.Adam(rnn.parameters(),lr=LR) #optimize all cnn parameters
loss_func=nn.MSELoss()
h_state=None #為了下面使用的時(shí)候更容易
for step in range(60): #取60步的數(shù)據(jù)點(diǎn)(以便擬合),然后將其放入x_np和y_np中去計(jì)算它們
x=Variavle(torch.from_numpy(x_np[np.newaxis,:,np.newaxis])) y=Variable(torch.from_numpy(x_np[np.newaxis,:,np.newaxis])) #將x和y包起來(lái)進(jìn)行,后面那個(gè)就是維度懂版,除time_step保留原來(lái)維度鹃栽,其余皆變,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包成一個(gè)包裹躯畴,以方便其改變的時(shí)候民鼓,可以進(jìn)行更新
loss=loss_funx(output,b_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
非監(jiān)督學(xué)習(xí)Autoencode
將圖片進(jìn)行打碼,在還原蓬抄。神經(jīng)網(wǎng)絡(luò)先壓縮再解壓
將圖片進(jìn)行數(shù)據(jù)壓縮丰嘉,可以得到精髓的部分(encode)用這個(gè)特征集代表我們所有的輸入。如若想要還原數(shù)據(jù)嚷缭,就需要解壓饮亏,可以通過(guò)輸入和輸出的對(duì)比不斷得到優(yōu)化的網(wǎng)絡(luò)。解壓出來(lái)的部分不斷優(yōu)化阅爽,更像路幸。
將一部分?jǐn)?shù)據(jù)壓縮解壓進(jìn)行學(xué)習(xí)。
AutoEncoder的類(lèi)
class AuroEncoder(nn.Module):
def _init_(self):
super(AutoEncoder,self)._init_()
self.encoder=nn.Sequential( #gengkuai
nn.Linear(28*28,128) #像素點(diǎn)是28*28
nn.Tanh(),
nn.Linear(128,64),
nn.Tanh(),
nn.Linear(64,12),
nn.Linear(1,64),
nn.Tanh(),
nn.Linear(12,3)
)#這是一個(gè)不斷壓縮的過(guò)程付翁,下面會(huì)解碼解壓縮
self.decoder=nn.nn.Sequential( #gengkuai
nn.Linear(3,12) #像素點(diǎn)是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 生成對(duì)抗網(wǎng)絡(luò)Generative Adversarial Nets
屬于一種生成器百侧,利用一種東西生成更多更好的東西
數(shù)據(jù)=/結(jié)果
無(wú)意義隨機(jī)數(shù)--->good結(jié)果
(新手畫(huà)家)Generator《---->隨機(jī)數(shù)《-------->messy 畫(huà)× 好√
↑ ↓ ↓
Discriminator(新手鑒賞家)
最終生成新的Generator砰识,可將其用于其他很多方面
準(zhǔn)備代碼
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)
參數(shù)代碼,生成名畫(huà)和爛畫(huà)
#超參數(shù)
BATCH_SIZE=64
LR_G=0.0001 #generator(生成器)學(xué)習(xí)效率
LR_D=0.0001 #discriminator(判斷器)學(xué)習(xí)效率
N_IDEAS=5
ART_COMPONENTS=15 #線段上有15個(gè)點(diǎn)
PAINT_POINTS=np.vstack([np.linespce(-1,1,ART_COMPONENTS: for _in range(BATCH_SIZE))])#從-1~1的線段
名畫(huà)帆吻,
def aretist_works():
a=np.random.uniform(1,2,size=BATCH_SIZE)[:,np.newaxis] #1~2區(qū)間唇兑,最后面是維度,隨機(jī)生成畫(huà)龟劲。
批處理观话。一個(gè)參數(shù)
paintings =a*np.power(PAINT_POINTS,2)+(a-1) #這就是我們的畫(huà)予借,畫(huà)進(jìn)行的轉(zhuǎn)變。生成的區(qū)間就是爛畫(huà)和名畫(huà)之間的區(qū)間
paintings=torch.from_numpy(painting).float()#tensor轉(zhuǎn)化成numpy的形式
return Variable(paintings) #將其包起來(lái)
G=nn.Sequential( #一個(gè)隨機(jī)靈感--->名畫(huà)
nn.Linear(N_IDEAS,128)#前者為隨機(jī)靈感频蛔,由上文知灵迫,其值為5
nn.ReLU(),
nn.Linear(128,ART_COMPONENTS), #最后生成的畫(huà)/名畫(huà)
)
D=nn.Sequential( #可接收名畫(huà)也可接收隨意一作家所畫(huà)的畫(huà)
nn.Linear(ART_COMPONENTS,128)
nn.ReLU(),
nn.Linear(128,1), #1判定是否為名畫(huà)
nn.Sigmoid(),#轉(zhuǎn)化成百分比的形式,有多少概率是著名畫(huà)家所畫(huà)的畫(huà)
)
優(yōu)化
opt_D=torchoptim.Adam(D.parameters(),lr=LR_D)
opt_G=torchoptim.Adam(G.parameters(),lr=LR_D)
學(xué)習(xí)
for step in range(10000):
artist_paintings=artist_works() #名畫(huà)晦溪,隨機(jī)的瀑粥,但是是著名畫(huà)家畫(huà)的
G_idea=Variable(torch.randn(BATCH_SIZE,N_IDEAS))#生成隨機(jī)數(shù)
G_paintings=G(G_ideas)
prob_artist0=D(artist_paintings)
prob_artist1=D(G_paintings) #不知道是新手還是著名畫(huà)家畫(huà)的,所以需要用這兩個(gè)式子判別一下
D_loss=—torch.mean(torch.log(prob_artist0)+torch.log(1-prob_artist1)) #增加抽取到著名畫(huà)家的畫(huà)的可能性
G_loss=torch.log(1-prob_artist1)#想要增加自己被認(rèn)為是著名畫(huà)家的概率
opt_D.zero_grad()
D_loss.backward(retain_variable=True) #backward以后三圆,我要保留一下之前網(wǎng)絡(luò)參數(shù)狞换,給下一次backward使用
opt_D.step()
opt_G.zero_grad()
G_loss.backward()
opt_G.step()
#####可視化的代碼
不寫(xiě)了避咆,就是有關(guān)plt,我不會(huì)寫(xiě)修噪,到時(shí)看模板的查库。
##pytorch是動(dòng)態(tài)的
#過(guò)擬合
自負(fù)=過(guò)擬合
方法:增加數(shù)據(jù)量;變用正規(guī)化黄琼;y=Wx,cost=(Wx-real y)^2+abs(W);y=Wx,cost=(Wx-real y)^2+(W)^2;
我們更喜歡它學(xué)到一個(gè)普遍的形式樊销,所以過(guò)擬合不太好
##批標(biāo)準(zhǔn)化