SVHN02baseline學(xué)習(xí)

順著文檔理解代碼,加備注

import os, sys, glob, shutil, json

os.environ["CUDA_VISIBLE_DEVICES"]= '0'

import cv2

from PILimport Image

import numpyas np

from tqdmimport tqdm, tqdm_notebook

import torch

torch.manual_seed(0)

torch.backends.cudnn.deterministic= False

torch.backends.cudnn.benchmark= True

import torchvision.modelsas models

import torchvision.transformsas transforms

import torchvision.datasetsas datasets

import torch.nnas nn

import torch.nn.functionalas F

import torch.optimas optim

from torch.autogradimport Variable

from torch.utils.data.datasetimport Dataset

#定義好讀取圖像的Dataset的類

#屬性img_path, img_label, transform,方法__getitem__,__len__

class SVHNDataset(object):

? ? def __init__(self,img_path,img_label,transform=None):

? ? ? ? self.img_path= img_path

? ? ? ? self.img_label= img_label

? ? ? ? if transform is not None:

? ? ? ? ? ? self.transform= transform

? ? ? ? else:

? ? ? ? ? ? self.transform= None

? ? #返回index的圖像和標(biāo)簽

? ? def __getitem__(self,index):

? ? ? ? img= Image.open(self.img_path[index]).convert('RGB')

if self.transformis? not None :

? ? ? ? ? ? img= self.transform(img)

# 設(shè)置最?的字符?度為5個(gè)

? ? ? ? lbl= np.array(self.img_label[index],dtype= np.int)

#組合標(biāo)簽時(shí)用list隨意加入元素——np.array類型——張量

? ? ? ? lbl= list(lbl)+ (5-len(lbl))* [10]

return img,torch.from_numpy(np.array(lbl[:5]))

def __len__(self):

? ? ? ? return len(self.img_path)

#定義訓(xùn)練和驗(yàn)證數(shù)據(jù)的Dataset

def getDataSet():

? ? # 訓(xùn)練數(shù)據(jù)的Dataset

? ? #查找符合特定規(guī)則的文件路徑名,獲取所有的匹配路徑(用完全的路徑別用../)

? ? train_path= glob.glob(r'D:/competition/tianchi/cv/SVHN/input/mchar_train/mchar_train/*.png')

train_path.sort()

train_json= json.load(open('D:/competition/tianchi/cv/SVHN/input/train.json'))

#json格式:"000000.png": {"height": [219, 219], "label": [1, 9], "left": [246, 323], "top": [77, 81], "width": [81, 96]},

? ? #train_json[x]是dict,索引:D2['name'] = 'Bob'

? ? train_label= [train_json[x]['label']for xin train_json]

print(len(train_path),len(train_label))

#dataloader對(duì)dataset封裝以批量迭代讀取,圖像和標(biāo)簽讀取成SVHNDataset類碗殷,數(shù)據(jù)擴(kuò)充,

? ? #數(shù)據(jù)加載器。組合數(shù)據(jù)集和采樣器抹镊,并在數(shù)據(jù)集上提供單進(jìn)程或多進(jìn)程迭代器。

? ? train_loader= torch.utils.data.DataLoader(

SVHNDataset(train_path, train_label,#(input, target)

? ? transforms.Compose([#將多種變換組合在一起

? ? ? ? transforms.Resize((64,128)),#指定大小,縮放到固定尺?

? ? ? ? transforms.RandomCrop((60,120)),#在一個(gè)隨機(jī)的位置進(jìn)行裁

? ? ? ? transforms.ColorJitter(0.3,0.3,0.2),#隨機(jī)改變圖像的亮度對(duì)比度和飽和度

? ? ? ? transforms.RandomRotation(5),# 加?隨機(jī)旋轉(zhuǎn)

#convert a PIL image to tensor (HWC) in range [0,255] then to a torch.Tensor(CHW) in the range [0.0,1.0]

? ? ? ? transforms.ToTensor(),# 將圖?轉(zhuǎn)換為pytorch 的tesntor

#用給定的均值和標(biāo)準(zhǔn)差分別對(duì)每個(gè)通道的數(shù)據(jù)進(jìn)行正則化荤傲。均值(M1,…,Mn)垮耳,給定標(biāo)準(zhǔn)差(S1,…,Sn)

#output[channel] = (input[channel] - mean[channel]) / std[channel],如((0,1)-0.5)/0.5=(-1,1)

? ? ? ? transforms.Normalize([0.485,0.456,0.406], [0.229,0.224,0.225])

])),

batch_size=40,#每個(gè)batch加載多少個(gè)樣本

? ? #shuffle=True,? ? #在每個(gè)epoch重新打亂數(shù)據(jù),默認(rèn)false

? ? #num_workers=10,? #用多少個(gè)子進(jìn)程加載數(shù)據(jù)

? ? )

#驗(yàn)證數(shù)據(jù)的dataset

? ? val_path= glob.glob('D:/competition/tianchi/cv/SVHN/input/mchar_val/mchar_val/*.png')

val_path.sort()

val_json= json.load(open('D:/competition/tianchi/cv/SVHN/input/val.json'))

val_label= [val_json[x]['label']for xin val_json]

print(len(val_path),len(val_label))

val_loader= torch.utils.data.DataLoader(

SVHNDataset(val_path, val_label,

transforms.Compose([

transforms.Resize((60,120)),

# transforms.ColorJitter(0.3, 0.3, 0.2),

# transforms.RandomRotation(5),

? ? ? ? transforms.ToTensor(),

transforms.Normalize([0.485,0.456,0.406], [0.229,0.224,0.225])

])),

batch_size=40,

shuffle=False,

num_workers=10,)

return train_loader,val_loader

#output

train_loader,val_loader= getDataSet()#輸出應(yīng)當(dāng)為30000 30000 10000 10000

#構(gòu)建CNN模型

class SVHN_model_1(nn.Module):

? ? #super指代父類,繼承的時(shí)候遂黍,調(diào)用含super的各個(gè)的基類__init__函數(shù)

? ? def __init__(self):

? ? ? ? super(SVHN_model_1,self).__init__()

#cnn提取特征模塊

? ? ? ? #一個(gè)有序的容器终佛,神經(jīng)網(wǎng)絡(luò)模塊將按照在傳入構(gòu)造器的順序依次被添加到計(jì)算圖中執(zhí)行,同時(shí)以神經(jīng)網(wǎng)絡(luò)模塊為元素的有序字典也可以作為傳入?yún)?shù)雾家。

? ? ? ? self.cnn= nn.Sequential(

nn.Conv2d(3,16,kernel_size=(3,3),stride=(2,2)),

nn.ReLU(),

nn.MaxPool2d(2),

nn.Conv2d(16,32,kernel_size=(3,3),stride=(2,2)),

nn.ReLU(),

nn.MaxPool2d(2),

)

#對(duì)傳入數(shù)據(jù)應(yīng)用線性變換:y = A x+ b,(每個(gè)輸入樣本的大小,出大小,bias=False則圖層不會(huì)學(xué)習(xí)附加偏差铃彰。)

? ? ? ? self.fc1= nn.Linear(32 * 3 * 7,11)

self.fc2= nn.Linear(32 * 3 * 7,11)

self.fc3= nn.Linear(32 * 3 * 7,11)

self.fc4= nn.Linear(32 * 3 * 7,11)

self.fc5= nn.Linear(32 * 3 * 7,11)

self.fc6= nn.Linear(32 * 3 * 7,11)

#輸出經(jīng)過(guò)所有神經(jīng)網(wǎng)絡(luò)層的結(jié)果

? ? def forward(self,img):

? ? ? ? feat= self.cnn(img)#nn.Sequential

? ? ? ? #將一個(gè)多行的Tensor,拼接成一行

? ? ? ? feat= feat.view(feat.shape[0],-1)

#并聯(lián)6全連接,進(jìn)行分類

? ? ? ? c1= self.fc1(feat)

c2= self.fc2(feat)

c3= self.fc3(feat)

c4= self.fc4(feat)

c5= self.fc5(feat)

c6= self.fc6(feat)

return c1, c2, c3, c4, c5, c6

#model已經(jīng)經(jīng)過(guò)了cnn,有forward()方法出6個(gè)并聯(lián)全連接結(jié)果

model1= SVHN_model_1()

#使用在imageNet數(shù)據(jù)集上的與訓(xùn)練模型

class SVHN_model_2(nn.Module):

? ? def __init__(self):

? ? ? ? #?芯咧?

? ? ? ? super(SVHN_model_2,self).__init__()

model_conv= models.resnet18(pretrained=True)

#平均池化:輸出特征的個(gè)數(shù)等于輸入平面的個(gè)數(shù)牙捉,都為1*1的tensor,strides敬飒,paddings等參數(shù)都自適應(yīng)好了

? ? ? ? model_conv.avgpool= nn.AdaptiveAvgPool2d(1)

#迭代器:model.modules()會(huì)遍歷model中所有的子層邪铲,而model.children()僅會(huì)遍歷當(dāng)前層[[1, 2], 3]--[1, 2], 3。

? ? ? ? model_conv= nn.Sequential(*list(model_conv.children())[:-1])

self.cnn= model_conv

self.fc1= nn.Linear(512,11)

self.fc2= nn.Linear(512,11)

self.fc3= nn.Linear(512,11)

self.fc4= nn.Linear(512,11)

self.fc5= nn.Linear(512,11)

#與model1一樣

? ? def forward(self,img):

? ? ? ? feat= self.cnn(img)

# print(feat.shape)

? ? ? ? feat= feat.view(feat.shape[0],-1)

c1= self.fc1(feat)

c2= self.fc2(feat)

c3= self.fc3(feat)

c4= self.fc4(feat)

c5= self.fc5(feat)

return c1, c2, c3, c4, c5

model2= SVHN_model_2()

#訓(xùn)練數(shù)據(jù)

def trainData(train_loader,model):

? ? #s=nn.Softmax(dim=1)一列的和為1–NLLLoss --i=torch.log(s(input))

? ? #nn.NLLLoss(i,target) 把上面的輸出與Label對(duì)應(yīng)的那個(gè)值拿出來(lái)驶拱,再去掉負(fù)號(hào)霜浴,再求均值。

? ? criterion= nn.CrossEntropyLoss()#二分類損失函數(shù),是上面三步的綜合

? ? #優(yōu)化器對(duì)象Optimizer蓝纲,用來(lái)保存當(dāng)前的狀態(tài)阴孟,并能夠根據(jù)計(jì)算得到的梯度來(lái)更新參數(shù)晌纫。

? ? optimizer= torch.optim.Adam(model.parameters(),0.005)

loss_plot= []

c0_plot= []

#epoch訓(xùn)練過(guò)程

? ? for epochin range(1):

? ? ? ? for datain train_loader:

? ? ? ? ? ? c0, c1, c2, c3, c4, c5= model(data[0])

data[1]= data[1].long()

loss= criterion(c0, data[1][:,0])+\

criterion(c1, data[1][:,1])+\

criterion(c2, data[1][:,2])+\

criterion(c3, data[1][:,3])+\

criterion(c4, data[1][:,4])

#報(bào)錯(cuò)下面的data[1][:, 5]不存在

? ? ? ? ? ? ? ? ? #criterion(c5, data[1][:, 5])

? ? ? ? ? ? loss/= 5

? ? ? ? ? ? optimizer.zero_grad()

loss.backward()

optimizer.step()

loss_plot.append(loss.item())

c0_plot.append((c0.argmax(1)==data[1][:,0].sum().item()*1.0/c0.shape[0]))

print(epoch)

#trainData(train_loader,model1)

#每次epoch訓(xùn)練的過(guò)程

def train(train_loader,model,criterion,optimizer,epoch):

? ? # 切換模型為訓(xùn)練模式

? ? model.train()

#enumerate()將一個(gè)可遍歷的數(shù)據(jù)對(duì)象組合為一個(gè)索引序列,同時(shí)列出下標(biāo)和數(shù)據(jù)

? ? for i, datain enumerate(train_loader):

? ? ? ? c0, c1, c2, c3, c4, c5= model(data[0])

data[1]= data[1].long()

loss= criterion(c0, data[1][:,0])+ \

criterion(c1, data[1][:,1])+ \

criterion(c2, data[1][:,2])+ \

criterion(c3, data[1][:,3])+ \

criterion(c4, data[1][:,4])

# criterion(c5, data[1][:, 5])

? ? ? ? loss/= 5

? ? ? ? optimizer.zero_grad()#把模型中參數(shù)的梯度設(shè)為0

? ? ? ? loss.backward()#反向傳播(grad_fn就是Tensor專門保存其進(jìn)行過(guò)的數(shù)學(xué)運(yùn)算

? ? ? ? optimizer.step()#模型更新

def validate(val_loader,model,criterion):

? ? # 切換模型為預(yù)測(cè)模型

? ? model.eval()

val_loss= []

# 不記錄模型梯度信息

? ? with torch.no_grad():

? ? ? ? for i, datain enumerate(val_loader):

? ? ? ? ? ? c0, c1, c2, c3, c4, c5= model(data[0])

loss= criterion(c0, data[1][:,0])+ \

criterion(c1, data[1][:,1])+ \

criterion(c2, data[1][:,2])+ \

criterion(c3, data[1][:,3])+ \

criterion(c4, data[1][:,4])+ \

criterion(c5, data[1][:,5])

loss/= 6

? ? ? ? ? ? #不記錄模型梯度信息

? ? ? ? ? ? val_loss.append(loss.item())

return np.mean(val_loss)

def valCal(train_loader,val_loader,model):

? ? criterion= nn.CrossEntropyLoss()

optimizer= torch.optim.Adam(model.parameters(),0.001)

best_loss= 1000.0

? ? for epochin range(3):

? ? ? ? print('Epoch: ', epoch)

#每一次epoch都對(duì)訓(xùn)練集和VAL在同一個(gè)模型進(jìn)行計(jì)算

? ? ? ? train(train_loader,model, criterion, optimizer, epoch)

print('train_over')

val_loss= validate(val_loader,model, criterion)

print('val_over')

# 記錄下驗(yàn)證集精度

? ? ? ? if val_loss< best_loss:

? ? ? ? ? ? best_loss= val_loss

torch.save(model.state_dict(),'./model.pt')

valCal(train_loader,val_loader,model1)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市永丝,隨后出現(xiàn)的幾起案子锹漱,更是在濱河造成了極大的恐慌,老刑警劉巖慕嚷,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哥牍,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡喝检,警方通過(guò)查閱死者的電腦和手機(jī)嗅辣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)挠说,“玉大人澡谭,你說(shuō)我怎么就攤上這事∷鸺螅” “怎么了蛙奖?”我有些...
    開(kāi)封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)杆兵。 經(jīng)常有香客問(wèn)我雁仲,道長(zhǎng),這世上最難降的妖魔是什么琐脏? 我笑而不...
    開(kāi)封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任攒砖,我火速辦了婚禮,結(jié)果婚禮上日裙,老公的妹妹穿的比我還像新娘祭衩。我一直安慰自己,他們只是感情好阅签,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蝎抽,像睡著了一般政钟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上樟结,一...
    開(kāi)封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天养交,我揣著相機(jī)與錄音,去河邊找鬼瓢宦。 笑死碎连,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的驮履。 我是一名探鬼主播鱼辙,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼廉嚼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了倒戏?” 一聲冷哼從身側(cè)響起怠噪,我...
    開(kāi)封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎杜跷,沒(méi)想到半個(gè)月后傍念,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡葛闷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年憋槐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片淑趾。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡阳仔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出治笨,到底是詐尸還是另有隱情驳概,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布旷赖,位于F島的核電站顺又,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏等孵。R本人自食惡果不足惜稚照,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望俯萌。 院中可真熱鬧果录,春花似錦、人聲如沸咐熙。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)棋恼。三九已至返弹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間爪飘,已是汗流浹背义起。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留师崎,地道東北人默终。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親齐蔽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子两疚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348