pytorch在fintune時(shí)將sequential中的層輸出方法,以vgg為例
有時(shí)候我們?cè)趂intune時(shí)發(fā)現(xiàn)pytorch把許多層都集合在一個(gè)sequential里,但是我們希望能把中間層的結(jié)果引出來做下一步操作,于是我自己琢磨了一個(gè)方法,以vgg為例,有點(diǎn)僵硬哈!
首先pytorch自帶的vgg16模型的網(wǎng)絡(luò)結(jié)構(gòu)如下:
VGG( (features): Sequential( (0): Conv2d (3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU(inplace) (2): Conv2d (64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (3): ReLU(inplace) (4): MaxPool2d(kernel_size=(2, 2), stride=(2, 2), dilation=(1, 1)) (5): Conv2d (64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (6): ReLU(inplace) (7): Conv2d (128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (8): ReLU(inplace) (9): MaxPool2d(kernel_size=(2, 2), stride=(2, 2), dilation=(1, 1)) (10): Conv2d (128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (11): ReLU(inplace) (12): Conv2d (256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (13): ReLU(inplace) (14): Conv2d (256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (15): ReLU(inplace) (16): MaxPool2d(kernel_size=(2, 2), stride=(2, 2), dilation=(1, 1)) (17): Conv2d (256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (18): ReLU(inplace) (19): Conv2d (512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (20): ReLU(inplace) (21): Conv2d (512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (22): ReLU(inplace) (23): MaxPool2d(kernel_size=(2, 2), stride=(2, 2), dilation=(1, 1)) (24): Conv2d (512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (25): ReLU(inplace) (26): Conv2d (512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (27): ReLU(inplace) (28): Conv2d (512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (29): ReLU(inplace) (30): MaxPool2d(kernel_size=(2, 2), stride=(2, 2), dilation=(1, 1)) ) (classifier): Sequential( (0): Linear(in_features=25088, out_features=4096) (1): ReLU(inplace) (2): Dropout(p=0.5) (3): Linear(in_features=4096, out_features=4096) (4): ReLU(inplace) (5): Dropout(p=0.5) (6): Linear(in_features=4096, out_features=1000) ) )
我們需要fintune vgg16的features部分,并且我希望把3,8, 15, 22, 29這五個(gè)作為輸出進(jìn)一步操作。我的想法是自己寫一個(gè)vgg網(wǎng)絡(luò),這個(gè)網(wǎng)絡(luò)參數(shù)與pytorch的網(wǎng)絡(luò)一致但是保證我們需要的層輸出在sequential外。于是我寫的網(wǎng)絡(luò)如下:
class our_vgg(nn.Module): def __init__(self): super(our_vgg, self).__init__() self.conv1 = nn.Sequential( # conv1 nn.Conv2d(3, 64, 3, padding=35), nn.ReLU(inplace=True), nn.Conv2d(64, 64, 3, padding=1), nn.ReLU(inplace=True), ) self.conv2 = nn.Sequential( # conv2 nn.MaxPool2d(2, stride=2, ceil_mode=True), # 1/2 nn.Conv2d(64, 128, 3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(128, 128, 3, padding=1), nn.ReLU(inplace=True), ) self.conv3 = nn.Sequential( # conv3 nn.MaxPool2d(2, stride=2, ceil_mode=True), # 1/4 nn.Conv2d(128, 256, 3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(256, 256, 3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(256, 256, 3, padding=1), nn.ReLU(inplace=True), ) self.conv4 = nn.Sequential( # conv4 nn.MaxPool2d(2, stride=2, ceil_mode=True), # 1/8 nn.Conv2d(256, 512, 3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(512, 512, 3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(512, 512, 3, padding=1), nn.ReLU(inplace=True), ) self.conv5 = nn.Sequential( # conv5 nn.MaxPool2d(2, stride=2, ceil_mode=True), # 1/16 nn.Conv2d(512, 512, 3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(512, 512, 3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(512, 512, 3, padding=1), nn.ReLU(inplace=True), ) def forward(self, x): conv1 = self.conv1(x) conv2 = self.conv2(conv1) conv3 = self.conv3(conv2) conv4 = self.conv4(conv3) conv5 = self.conv5(conv4) return conv5
接著就是copy weights了:
def convert_vgg(vgg16):#vgg16是pytorch自帶的
net = our_vgg()# 我寫的vgg
vgg_items = net.state_dict().items()
vgg16_items = vgg16.items()
pretrain_model = {}
j = 0
for k, v in net.state_dict().iteritems():#按順序依次填入
v = vgg16_items[j][1]
k = vgg_items[j][0]
pretrain_model[k] = v
j += 1
return pretrain_model
## net是我們最后使用的網(wǎng)絡(luò),也是我們想要放置weights的網(wǎng)絡(luò)
net = net()
print ('load the weight from vgg')
pretrained_dict = torch.load('vgg16.pth')
pretrained_dict = convert_vgg(pretrained_dict)
model_dict = net.state_dict()
# 1. 把不屬于我們需要的層剔除
pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
# 2. 把參數(shù)存入已經(jīng)存在的model_dict
model_dict.update(pretrained_dict)
# 3. 加載更新后的model_dict
net.load_state_dict(model_dict)
print ('copy the weight sucessfully')
這樣我就基本達(dá)成目標(biāo)了,注意net也就是我們要使用的網(wǎng)絡(luò)fintune部分需要和our_vgg一致。
以上這篇pytorch在fintune時(shí)將sequential中的層輸出方法,以vgg為例就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python簡(jiǎn)單圖片操作:打開\顯示\保存圖像方法介紹
這篇文章主要介紹了python簡(jiǎn)單圖片操作:打開\顯示\保存圖像方法介紹,還涉及將圖片保存為灰度圖的簡(jiǎn)單方法示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
python?使用第三方庫(kù)requests-toolbelt?上傳文件流的示例
這篇文章主要介紹了python?使用第三方庫(kù)requests-toolbelt?上傳文件流,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09
Python構(gòu)造函數(shù)與析構(gòu)函數(shù)超詳細(xì)分析
在python之中定義一個(gè)類的時(shí)候會(huì)在類中創(chuàng)建一個(gè)名為__init__的函數(shù),這個(gè)函數(shù)就叫做構(gòu)造函數(shù)。它的作用就是在實(shí)例化類的時(shí)候去自動(dòng)的定義一些屬性和方法的值,而析構(gòu)函數(shù)恰恰是一個(gè)和它相反的函數(shù),這篇文章主要介紹了Python構(gòu)造函數(shù)與析構(gòu)函數(shù)2022-11-11
使用Python實(shí)現(xiàn)跳一跳自動(dòng)跳躍功能
這篇文章主要介紹了使用Python實(shí)現(xiàn)跳一跳自動(dòng)跳躍功能,本文圖文并茂通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07
Python實(shí)現(xiàn)的爬取百度文庫(kù)功能示例
這篇文章主要介紹了Python實(shí)現(xiàn)的爬取百度文庫(kù)功能,結(jié)合實(shí)例形式分析了Python針對(duì)百度文庫(kù)的爬取、編碼轉(zhuǎn)換、文件保存等相關(guān)操作技巧,需要的朋友可以參考下2019-02-02
Python滲透測(cè)試入門之Scapy庫(kù)的使用詳解
Scapy?是一個(gè)用來解析底層網(wǎng)絡(luò)數(shù)據(jù)包的Python模塊和交互式程序,該程序?qū)Φ讓影幚磉M(jìn)行了抽象打包,使得對(duì)網(wǎng)絡(luò)數(shù)據(jù)包的處理非常簡(jiǎn)便。本文就來聊聊它的具體使用,希望對(duì)大家有所幫助2023-03-03
Python的SQLalchemy模塊連接與操作MySQL的基礎(chǔ)示例
SQLalchemy是Python世界中驅(qū)動(dòng)MySQL的一款高人氣模塊,這里我們從入門開始來看一下Python的SQLalchemy模塊連接與操作MySQL的基礎(chǔ)示例:2016-07-07

