大挪耗

飞机小鸟图片分辨卷积

%matplotlib inline
from matplotlib import pyplot as plt
import numpy as np
import collections

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

torch.set_default_tensor_type('torch.FloatTensor')
torch.manual_seed(123)

#定义类别的名称
class_namess=["airplane", "automobile", "bird", "cat", "deer","dog", "frog", "horse", "ship", "truck"]

#加载CIFAR数据集,训练集
from torchvision import datasets, transforms
data_path="data/8/cifae-10/"
cifar10=datasets.CIFAR10(data_path, train=True, download=True,transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4915, 0.4823, 0.4468), (0.2470, 0.2435, 0.2616))]))

#加载验证集
cifar10_val=datasets.CIFAR10(data_path,train=False,download=True,transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4915, 0.4823, 0.4468), (0.2470, 0.2435, 0.2616))]))

#再把鸟和飞机摘出来,重新标注标签
label_map={0:0,2:1}
class_names=["airplane","bird"]
cifar2=[(img,label_map[label])for img,label in cifar10 if label in [0,2]]
cifar2_val=[(img,label_map[label])for img,label in cifar10_val if label in [0,2]]
Files already downloaded and verified
Files already downloaded and verified

In [38]:

conv=nn.Conv2d(3,16,kernel_size=3)
conv

Out[38]:

Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1))

In [39]:

conv.weight.shape,conv.bias.shape

Out[39]:

(torch.Size([16, 3, 3, 3]), torch.Size([16]))

In [40]:

img,_=cifar2[0]
output=conv(img.unsqueeze(0))
img.unsqueeze(0).shape,output.shape

Out[40]:

(torch.Size([1, 3, 32, 32]), torch.Size([1, 16, 30, 30]))

In [41]:

plt.figure(figsize=(10,4.8))
axl=plt.subplot(1,2,1)
plt.title("output")
plt.imshow(output[0,0].detach(),cmap="gray")
plt.subplot(1,2,2,sharex=axl,sharey=axl)
plt.imshow(img.mean(0),cmap="gray")
plt.title("input")
plt.show()

In [42]:

conv=nn.Conv2d(3,16,kernel_size=3,padding=1)
img,_=cifar2[0]
output=conv(img.unsqueeze(0))
img.unsqueeze(0).shape,output.shape

Out[42]:

(torch.Size([1, 3, 32, 32]), torch.Size([1, 16, 32, 32]))

In [43]:

with torch.no_grad():
    conv.bias.zero_()
with torch.no_grad():
    conv.weight.fill_(1.0/9.0)

output=conv(img.unsqueeze(0))
plt.figure(figsize=(10,4.8))
axl=plt.subplot(1,2,1)
plt.title("output")
plt.imshow(output[0,0].detach(),cmap="gray")
plt.subplot(1,2,2,sharex=axl,sharey=axl)
plt.imshow(img.mean(0),cmap="gray")
plt.title("input")
plt.show()

In [44]:

conv=nn.Conv2d(3,1,kernel_size=3,padding=1)

with torch.no_grad():
    conv.weight[:]=torch.tensor([[-1.0,0.0,1.0],[-1.0,0.0,1.0],[-1.0,0.0,1.0]])
    conv.bias.zero_()

output=conv(img.unsqueeze(0))
plt.figure(figsize=(10,4.8))
axl=plt.subplot(1,2,1)
plt.title("output")
plt.imshow(output[0,0].detach(),cmap="gray")
plt.subplot(1,2,2,sharex=axl,sharey=axl)
plt.imshow(img.mean(0),cmap="gray")
plt.title("input")
plt.show()

池化

In [45]:

model=nn.Sequential(
    nn.Conv2d(3,16,kernel_size=3,padding=1),
    nn.Tanh(),
    nn.MaxPool2d(2),
    nn.Conv2d(16,16,kernel_size=3,padding=1),
    nn.Tanh(),
    nn.MaxPool2d(2),
    
    nn.Linear(8*8*8,32),
    nn.Tanh(),
    nn.Linear(32,2)
)
numel_list=[p.numel() for p in model.parameters()]
sum(numel_list),numel_list

Out[45]:

(19250, [432, 16, 2304, 16, 16384, 32, 64, 2])

In [46]:

class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.conv1=nn.Conv2d(3,16,kernel_size=3,padding=1)
        self.conv2=nn.Tanh()
        self.pool1=nn.MaxPool2d(2)
        
        self.conv2=nn.Conv2d(16,16,kernel_size=3,padding=1)
        self.act2= nn.Tanh()
        self.pool2=nn.MaxPool2d(2)
        
        self.fc1=nn.Linear(8*8*8,32)
        self.act3= nn.Tanh()
        self.fc2=nn.Linear(32,2)
        
    def forward(self,x):
        out = self.pool1(self.act1(self.conv1(x)))
        out = self.pool2(self.act2(self.conv2(out)))
        out = out.view(-1,8*8*8)
        out = self.act3(self.fc1(out))
        out = self.fc2(out)
        return out
    
        

In [47]:

import torch.nn.functional as F

In [48]:

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1=nn.Conv2d(3,16,kernel_size=3,padding=1)
        self.conv2=nn.Conv2d(16,8,kernel_size=3,padding=1)
        self.fc1=nn.Linear(8*8*8,32)
        self.fc2=nn.Linear(32,2)
        
    def forward(self,x):
        out=F.max_pool2d(torch.tanh(self.conv1(x)),2)
        out=F.max_pool2d(torch.tanh(self.conv2(out)),2)
        out = out.view(-1,8*8*8)
        out = torch.tanh(self.fc1(out))
        out = self.fc2(out)
        return out
        

训练模型

In [49]:

import datetime

In [50]:

def train_loop(n_epochs,optimizer,model,loss_fn,train_loader):
    for epoch in range(1,n_epochs+1):
        loss_train=0.0
        for imgs,labels in train_loader:
            outputs=model(imgs)
            loss = loss_fn(outputs,labels)
            
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            
            loss_train+=loss.item()
        if epoch==1 or epoch % 10 == 0:
            print('{} epoch {}, Training Loss: {:.4f}'.format(datetime.datetime.now(),epoch,loss_train/ len(train_loader)))       

In [51]:

train_loader=torch.utils.data.DataLoader(cifar2,batch_size=64,shuffle=True)

model=Net()
optimizer=optim.SGD(model.parameters(),lr=1e-2,)
loss_fn=nn.CrossEntropyLoss()

train_loop(
    n_epochs=100,
    optimizer=optimizer,
    model=model,
    loss_fn=loss_fn,
    train_loader=train_loader,
)
2025-01-18 11:05:54.452644 epoch 1, Training Loss: 0.5669
2025-01-18 11:06:01.443614 epoch 10, Training Loss: 0.3434
2025-01-18 11:06:08.964075 epoch 20, Training Loss: 0.3072
2025-01-18 11:06:16.550718 epoch 30, Training Loss: 0.2764
2025-01-18 11:06:24.474405 epoch 40, Training Loss: 0.2524
2025-01-18 11:06:32.265278 epoch 50, Training Loss: 0.2309
2025-01-18 11:06:40.182867 epoch 60, Training Loss: 0.2109
2025-01-18 11:06:48.353061 epoch 70, Training Loss: 0.1975
2025-01-18 11:06:56.240187 epoch 80, Training Loss: 0.1830
2025-01-18 11:07:03.885278 epoch 90, Training Loss: 0.1692
2025-01-18 11:07:12.010916 epoch 100, Training Loss: 0.1593

In [52]:

train_loader=torch.utils.data.DataLoader(cifar2,batch_size=64,shuffle=True)
val_loader=torch.utils.data.DataLoader(cifar2_val,batch_size=64,shuffle=True)

def validate(model,train_loader,val_loader):
    for name,loader in [("train",train_loader),("val",val_loader)]:
        correct=0
        total=0
        
        with torch.no_grad():
            for imgs,labels in loader:
                outputs=model(imgs)
                _,predicted=torch.max(outputs,dim=1)
                total += labels.size(0)
                correct +=int((predicted==labels).sum())
                
        print("Accuracy {}: {:.2f}".format(name,correct/total))
        
validate(model,train_loader,val_loader)
                
Accuracy train: 0.94
Accuracy val: 0.90

In [53]:

#保存模型
torch.save(model.state_dict(),'birds_and_airplanes.pt')

In [54]:

#加载模型
loaded_model=Net()
loaded_model.load_state_dict(torch.load('birds_and_airplanes.pt'))
C:\Users\tanhaowen\AppData\Local\Temp\ipykernel_5560\505120885.py:3: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
  loaded_model.load_state_dict(torch.load('birds_and_airplanes.pt'))

Out[54]:

<All keys matched successfully>

In [55]:

# 使用gpu训练模型
device=(torch.device('cuda' if torch.cuda.is_available() else 'cpu'))
print(f"Training on device {device}")
Training on device cuda

In [56]:

import datetime

def train_loop(n_epochs,optimizer,model,loss_fn,train_loader):
    for epoch in range(1,n_epochs+1):
        loss_train=0.0
        for imgs,labels in train_loader:
            imgs=imgs.to(device=device)
            labels=labels.to(device=device)
            outputs=model(imgs)
            loss = loss_fn(outputs,labels) 
            
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            
            loss_train+=loss.item()
        
        if epoch==1 or epoch % 10 == 0:
            print("{} Epoch {},Trainging loss{}".format(datetime.datetime.now(),epoch,loss_train/ len(train_loader)))

train_loader=torch.utils.data.DataLoader(cifar2,batch_size=64,shuffle=True)

model=Net().to(device=device)
optimizer=optim.SGD(model.parameters(),lr=1e-2,)
loss_fn=nn.CrossEntropyLoss()

train_loop(
    n_epochs=100,
    optimizer=optimizer,
    model=model,
    loss_fn=loss_fn,
    train_loader=train_loader
)

        
2025-01-18 11:07:12.993692 Epoch 1,Trainging loss0.5774919248310624
2025-01-18 11:07:14.822029 Epoch 10,Trainging loss0.33247699137705905
2025-01-18 11:07:16.864327 Epoch 20,Trainging loss0.30183320971810895
2025-01-18 11:07:18.885874 Epoch 30,Trainging loss0.27957967806393935
2025-01-18 11:07:21.007782 Epoch 40,Trainging loss0.25747410525941544
2025-01-18 11:07:23.076285 Epoch 50,Trainging loss0.23804032361241662
2025-01-18 11:07:25.050501 Epoch 60,Trainging loss0.22230669409985754
2025-01-18 11:07:26.987403 Epoch 70,Trainging loss0.20533453340932822
2025-01-18 11:07:28.945509 Epoch 80,Trainging loss0.1917050355084383
2025-01-18 11:07:30.867017 Epoch 90,Trainging loss0.17810696173625387
2025-01-18 11:07:32.824421 Epoch 100,Trainging loss0.16675861360161168

In [57]:

# 优化方案:增加模型宽度
class Net(nn.Module):
    def __init__(self,n_classes=32):
        super().__init__()
        self.conv1=nn.Conv2d(3,32,kernel_size=3,padding=1)
        self.conv2=nn.Conv2d(32,16,kernel_size=3,padding=1)
        self.fc1=nn.Linear(16*8*8,32)
        self.fc2=nn.Linear(32,2)
        
    def forward(self,x):
        out = F.max_pool2d(torch.tanh(self.conv1(x)),2)
        out = F.max_pool2d(torch.tanh(self.conv2(out)),2)
        out = out.view(-1,16*8*8)
        out=torch.tanh(self.fc1(out))
        out = self.fc2(out)
        return out
        

In [58]:

class NetWidth(nn.Module):
    def __init__(self,n_chans1=32):
        super().__init__()
        self.n_chans1=n_chans1
        self.conv1=nn.Conv2d(3,n_chans1,kernel_size=3,padding=1)
        self.conv2=nn.Conv2d(n_chans1,n_chans1//2,kernel_size=3,padding=1)
        
        self.fc1=nn.Linear(16*8*n_chans1,32)
        self.fc2=nn.Linear(32,2)
    
    def forward(self,x):
        out = F.max_pool2d(torch.tanh(self.conv1(x)),2)
        out = F.max_pool2d(torch.tanh(self.conv2(out)),2)
        out = out.view(-1,16*8*8)
        out=torch.tanh(self.fc1(out))
        out = self.fc2(out)
        return out
        
        

In [59]:

# 优化方案:正则化
def training_loop_12reg(n_epochs,optimizer,model,loss_fn,train_loader):
    for epoch in range(1,n_epochs+1):
        loss_train=0.0
        for imgs,labels in train_loader:
            imgs=imgs.to(device=device)
            labels=labels.to(device=device)
            outputs=model(imgs)
            loss=loss_fn(outputs,labels)
            
            l2_lambda=0.001
            l2_norn=sum(p.pow(2).sum() for p in model.parameters())
            loss=loss+l2_lambda*l2_norn
            
            optimizer.zero_grad()
            loss.backwark()
            optimizer.step()
            
            loss_train+=loss.item()
        
        if epoch==1 or epoch % 10 == 0:
            print("{} Epoch {},Training loss{}".format(datetime.datetime.now(),epoch,loss_train/ len(train_loader)))
        

In [60]:

class NetDropout(nn.Module):
    def __init__(self,n_chans1=32):
        super().__init__()
        self.n_chans1=n_chans1
        self.conv1=nn.Conv2d(3,n_chans1,kernel_size=3,padding=1)
        self.conv1_dropout=nn.Dropout2d(p=0.4)
        self.conv2=nn.Conv2d(n_chans1,n_chans1//2,kernel_size=3,padding=1)
        self.conv2_dropout=nn.Dropout2d(p=0.4)
        self.fc1=nn.Linear(16*8*n_chans1,32)
        self.fc2=nn.Linear(32,2)
        
    def forward(self,x):
        out = F.max_pool2d(torch.tanh(self.conv1(x)),2)
        out =self.conv1_dropout(out)
        
        out = F.max_pool2d(torch.tanh(self.conv2(x)),2)
        out = self.conv2_dropout(out)
        
        out = out.view(-1,8*8*self.n_chans1//2)
        out=torch.tanh(self.fc1(out))
        out = self.fc2(out)
        return out
        
        
        

In [61]:

class NetBatchNorn(nn.Module):
    def __init__(self,n_chans1=32):
        super().__init__()
        self.n_chans1=n_chans1
        self.conv1=nn.Conv2d(3,n_chans1,kernel_size=3,padding=1)
        self.conv1_batchnorm=nn.BatchNorm2d(num_features=n_chans1)
        self.conv2=nn.Conv2d(n_chans1,n_chans1//2,kernel_size=3,padding=1)
        self.conv2_batchnorm=nn.BatchNorm2d(num_features=n_chans1//2)
        self.fc1=nn.Linear(8*8*n_chans1//2,32)
        self.fc2=nn.Linear(32,2)
        
    def forward(self,x):
        out=self.conv1_batchnorm(self.conv1(x))
        out=F.max_pool2d(torch.tanh(out),2)
        out=self.conv2_batchnorm(self.conv2(out))
        out=F.max_pool2d(torch.tanh(out),2)
        
        

In [62]:

# 增加模型的深度

In [63]:

class ResNetTest(nn.Module):
    def __init__(self,n_chans1=32):
        super().__init__()
        self.n_chans1=n_chans1
        self.conv1=nn.Conv2d(3,n_chans1,kernel_size=3,padding=1)
        self.conv2=nn.Conv2d(n_chans1,n_chans1//2,padding=1)
        self.conv3=nn.Conv2d(n_chans1//2,n_chans1//2,kernel_size=3,padding=1)
        self.fc1=nn.Linear(4*4*n_chans1//2,32)
        self.fc2=nn.Linear(32,2)
        
    def forward(self,x):
        out = F.max_pool2d(torch.tanh(self.conv1(x)),2)
        out = F.max_pool2d(torch.tanh(self.conv2(out)),2)
        out1=out
        out = F.max_pool2d(torch.tanh(self.conv3(out1))+out1,2)
        out=out.view(-1,4*4*self.n_chans1//2)
        out=torch.tanh(self.fc1(out))
        out=self.fc2(out)
        return out
        

In [64]:

import datetime
def train_loop(n_epochs,optimizer,model,loss_fn,train_loader):
    for epoch in range(1,n_epochs+1):
        loss_train=0.0
        for imgs,labels in train_loader:
            imgs=imgs.to(device=device)
            labels=labels.to(device=device)
            outputs=model(imgs)
            loss=loss_fn(outputs,labels)
            
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            
            
            

In [65]:

import datetime

def train_loop(n_epochs,optimizer,model,loss_fn,train_loader):
    for epoch in range(1,n_epochs+1):
        loss_train=0.0
        for imgs,labels in train_loader:
            imgs=imgs.to(device=device)
            labels=labels.to(device=device)
            outputs=model(imgs)
            loss = loss_fn(outputs,labels) 
            
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            
            loss_train+=loss.item()
        
        if epoch==1 or epoch % 10 == 0:
            print("{} Epoch {},Trainging loss{}".format(datetime.datetime.now(),epoch,loss_train/ len(train_loader)))

train_loader=torch.utils.data.DataLoader(cifar2,batch_size=64,shuffle=True)

model=Net().to(device=device)
optimizer=optim.SGD(model.parameters(),lr=1e-2,)
loss_fn=nn.CrossEntropyLoss()

train_loop(
    n_epochs=100,
    optimizer=optimizer,
    model=model,
    loss_fn=loss_fn,
    train_loader=train_loader
)
2025-01-18 11:07:33.129450 Epoch 1,Trainging loss0.5390971137839518
2025-01-18 11:07:35.072852 Epoch 10,Trainging loss0.3141013920117336
2025-01-18 11:07:37.278568 Epoch 20,Trainging loss0.2712045578155548
2025-01-18 11:07:39.430647 Epoch 30,Trainging loss0.24286607107159439
2025-01-18 11:07:41.834147 Epoch 40,Trainging loss0.21347075112306388
2025-01-18 11:07:44.318877 Epoch 50,Trainging loss0.18563196461671477
2025-01-18 11:07:46.807634 Epoch 60,Trainging loss0.16053212640486705
2025-01-18 11:07:49.275878 Epoch 70,Trainging loss0.13700199025167023
2025-01-18 11:07:51.757971 Epoch 80,Trainging loss0.12101342035516811
2025-01-18 11:07:54.277553 Epoch 90,Trainging loss0.09994453897664121
2025-01-18 11:07:56.746458 Epoch 100,Trainging loss0.0841510158008451

In [67]:

train_loader=torch.utils.data.DataLoader(cifar2,batch_size=64,shuffle=True)
val_loader=torch.utils.data.DataLoader(cifar2_val,batch_size=64,shuffle=True)

def validate(model,train_loader,val_loader):
    for name,loader in [("train",train_loader),("val",val_loader)]:
        correct=0
        total=0
        
        with torch.no_grad():
            for imgs,labels in loader:
                imgs=imgs.to(device=device)
                labels=labels.to(device=device)
                outputs=model(imgs)
                _,predicted=torch.max(outputs,dim=1)
                total += labels.size(0)
                correct +=int((predicted==labels).sum())
                
        print("Accuracy {}: {:.2f}".format(name,correct/total))
        
validate(model,train_loader,val_loader)
Accuracy train: 0.97
Accuracy val: 0.90

In [ ]:

 


已发布

分类

可以收藏大挪耗一下。下载麻烦点城通网盘,站长保证下载速度,不会限速的,放心点就是了;分卷,安卓下载为txt:程序下载为url,不会下载参考不会下载。如果你想让本站活的久一点,请直接捐助

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注