ADD file via upload
This commit is contained in:
parent
4201f20d35
commit
7c54729011
|
@ -0,0 +1,257 @@
|
||||||
|
import torch
|
||||||
|
import torchvision
|
||||||
|
from torch.utils.data import Dataset, DataLoader
|
||||||
|
from torchvision import transforms,datasets
|
||||||
|
from torchvision.transforms import ToTensor
|
||||||
|
import numpy as np
|
||||||
|
import torch.nn as nn
|
||||||
|
import torch.nn.functional as F
|
||||||
|
import torch.optim as optim
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
device=torch.device("cpu")
|
||||||
|
|
||||||
|
cropbox=(0,0,316,316)
|
||||||
|
learning_rate = 1e-3
|
||||||
|
batch_size = 50
|
||||||
|
epochs = 12
|
||||||
|
|
||||||
|
def readimg(path):
|
||||||
|
txt=open(path+"\\data.txt",'r')
|
||||||
|
lines=txt.readlines()
|
||||||
|
txt.close()
|
||||||
|
imgs=[]
|
||||||
|
labels=[]
|
||||||
|
for line in lines:
|
||||||
|
line = line.rstrip()
|
||||||
|
word = line.split(' ')
|
||||||
|
img = Image.open(path+'\\'+word[0])
|
||||||
|
img_2=img.crop(cropbox)
|
||||||
|
img_ten=transforms.ToTensor()(np.array(img_2))
|
||||||
|
imgs.append(img_ten)
|
||||||
|
if word[1]=='0':
|
||||||
|
labels.append(torch.zeros(1))
|
||||||
|
else:
|
||||||
|
labels.append(torch.ones(1))
|
||||||
|
return imgs,labels
|
||||||
|
|
||||||
|
|
||||||
|
class CustomedDataSet(Dataset):
|
||||||
|
def __init__(self, train=True, train_x = None, train_y = None, test_x = None, test_y = None, val = False, transform = None):
|
||||||
|
self.train = train
|
||||||
|
self.val = val
|
||||||
|
self.transform = transform
|
||||||
|
if self.train:
|
||||||
|
self.dataset=train_x
|
||||||
|
self.labels=train_y
|
||||||
|
elif val:
|
||||||
|
self.dataset=test_x
|
||||||
|
self.labels=test_y
|
||||||
|
else:
|
||||||
|
self.dataset= test_x
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
if self.train:
|
||||||
|
return torch.Tensor(self.dataset[index]).to(device), torch.Tensor(self.labels[index]).to(device)
|
||||||
|
elif self.val:
|
||||||
|
return torch.Tensor(self.dataset[index]).to(device), torch.Tensor(self.labels[index]).to(device)
|
||||||
|
else:
|
||||||
|
return torch.Tensor(self.dataset[index]).to(device)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.dataset)
|
||||||
|
|
||||||
|
|
||||||
|
class CNN(nn.Module):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.features=nn.Sequential(
|
||||||
|
nn.Conv2d(3,6, kernel_size=5),
|
||||||
|
nn.ReLU(inplace=True),
|
||||||
|
nn.MaxPool2d(kernel_size=2,stride=2),
|
||||||
|
nn.Conv2d(6,12, kernel_size=5),
|
||||||
|
nn.ReLU(inplace=True),
|
||||||
|
nn.MaxPool2d(kernel_size=2,stride=2),
|
||||||
|
nn.Conv2d(12,24,kernel_size=5,stride=1),
|
||||||
|
nn.ReLU(inplace=True),
|
||||||
|
nn.Conv2d(24,24,kernel_size=5,stride=1),
|
||||||
|
nn.ReLU(inplace=True),
|
||||||
|
nn.Conv2d(24,48,kernel_size=5,stride=1),
|
||||||
|
nn.ReLU(inplace=True),
|
||||||
|
nn.MaxPool2d(kernel_size=2,stride=2),
|
||||||
|
)
|
||||||
|
|
||||||
|
# 请把之前 Network1 的 self.fc1 复制到这里:
|
||||||
|
# self.fc1 = nn.Linear(in_features=XXX, out_features=120)
|
||||||
|
|
||||||
|
self.classifier=nn.Sequential(
|
||||||
|
nn.Linear(32*32*48,2048),
|
||||||
|
nn.ReLU(inplace=True),
|
||||||
|
#nn.Dropout(0.5),
|
||||||
|
nn.Linear(2048,1024),
|
||||||
|
nn.ReLU(inplace=True),
|
||||||
|
#nn.Dropout(0.5),
|
||||||
|
nn.Linear(1024,1),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def forward(self, t):
|
||||||
|
t=self.features(t)
|
||||||
|
# 特别注意:最后一个卷积层的输出在流入全连接层之前,要对激活值的维度进行变换,变换后的张量
|
||||||
|
# 是二维张量,其中 dim0 对应该批次中的不同样本,dim1 对应每个样本流向全连接层的输入激活向量。
|
||||||
|
# 请完成如下代码。
|
||||||
|
|
||||||
|
# dim0:一个批次的样本数
|
||||||
|
# dim1:每一个样本的输入激活向量长度
|
||||||
|
|
||||||
|
# t = t.reshape(XXX,XXX)
|
||||||
|
t = t.reshape(batch_size,32*32*48)
|
||||||
|
|
||||||
|
t = self.classifier(t)
|
||||||
|
|
||||||
|
return t
|
||||||
|
|
||||||
|
class DeviationLoss(nn.Module):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def forward(self, y_pred, y_true):
|
||||||
|
confidence_margin = 5.
|
||||||
|
#ref = torch.normal(mean=0., std=torch.full([5000], 1.)).cuda()
|
||||||
|
#dev = (y_pred - torch.mean(ref)) / torch.std(ref)
|
||||||
|
dev = y_pred
|
||||||
|
inlier_loss = torch.abs(dev)
|
||||||
|
#outlier_loss = torch.abs((confidence_margin - dev).clamp_(min=0.))
|
||||||
|
outlier_loss = torch.abs((confidence_margin - torch.abs(dev)))
|
||||||
|
dev_loss = (1 - y_true) * inlier_loss + y_true * outlier_loss
|
||||||
|
#print("y_pred:",y_pred.shape,'y_true:',y_true.shape,'mean_loss:',torch.mean(dev_loss).item())
|
||||||
|
return torch.mean(dev_loss*(1+10*y_true))
|
||||||
|
|
||||||
|
def pred_to_label(preds):
|
||||||
|
a = torch.abs(preds)
|
||||||
|
# 保证和a相同的维度大小
|
||||||
|
zero = torch.zeros_like(a)
|
||||||
|
one = torch.ones_like(a)
|
||||||
|
# a中大于5的用one(1)替换,否则a替换,即不变
|
||||||
|
a = torch.where(a >= 5.0, one, zero)
|
||||||
|
# a中小于5的用zero(0)替换,否则a替换,即不变
|
||||||
|
return a
|
||||||
|
|
||||||
|
def get_tp(preds,labels):
|
||||||
|
a=pred_to_label(preds)
|
||||||
|
two=2.0*torch.ones_like(labels)
|
||||||
|
b=torch.where(labels==0.0,two,labels)
|
||||||
|
return a.eq(b).sum().item()
|
||||||
|
|
||||||
|
def get_tn(preds,labels):
|
||||||
|
a=pred_to_label(preds)
|
||||||
|
two=2.0*torch.ones_like(labels)
|
||||||
|
b=torch.where(labels==1.0,two,labels)
|
||||||
|
return a.eq(b).sum().item()
|
||||||
|
|
||||||
|
def get_fp(preds,labels):
|
||||||
|
a=pred_to_label(preds)
|
||||||
|
two=2.0*torch.ones_like(labels)
|
||||||
|
one=torch.ones_like(labels)
|
||||||
|
b=torch.where(labels==0.0,one,two)
|
||||||
|
return a.eq(b).sum().item()
|
||||||
|
|
||||||
|
def get_fn(preds,labels):
|
||||||
|
a=pred_to_label(preds)
|
||||||
|
two=2.0*torch.ones_like(labels)
|
||||||
|
zero=torch.zeros_like(labels)
|
||||||
|
b=torch.where(labels==1.0,zero,two)
|
||||||
|
return a.eq(b).sum().item()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
network=CNN()
|
||||||
|
#network = torchvision.models.alexnet(pretrained=False)
|
||||||
|
new_train_x,new_train_y=readimg("train")
|
||||||
|
train_set = CustomedDataSet(train_x = new_train_x, train_y = new_train_y)
|
||||||
|
new_val_x,new_val_y=readimg('val')
|
||||||
|
val_set = CustomedDataSet(test_x = new_val_x, test_y = new_val_y, train=False, val = True)
|
||||||
|
|
||||||
|
train_loader = DataLoader(dataset=train_set,batch_size=batch_size,shuffle=True,drop_last=True)
|
||||||
|
val_loader = DataLoader(dataset=val_set,batch_size=batch_size,shuffle=False,drop_last=True)
|
||||||
|
optimizer = torch.optim.SGD(network.parameters(), lr=learning_rate)
|
||||||
|
loss_func=DeviationLoss()
|
||||||
|
#loss_func=nn.BCEWithLogitsLoss()
|
||||||
|
for epoch in range(epochs): # 训练周期
|
||||||
|
total_loss = 0
|
||||||
|
total_tp = 0
|
||||||
|
total_tn = 0
|
||||||
|
total_fp = 0
|
||||||
|
total_fn = 0
|
||||||
|
count = 0
|
||||||
|
for batch in train_loader: # get a batch from the dataloader
|
||||||
|
# 读取样本数据,完成正向传播,计算损失
|
||||||
|
##################### please finish the code ########################
|
||||||
|
|
||||||
|
# images, labels = XXX
|
||||||
|
# preds = XXX
|
||||||
|
# loss = XXX
|
||||||
|
|
||||||
|
images, labels = batch
|
||||||
|
preds = network(images)
|
||||||
|
loss = loss_func(preds, labels)
|
||||||
|
|
||||||
|
################################ end ################################
|
||||||
|
# 下面这行非常重要,它使得优化器 (optimizer) 将权重的偏导重新归零;
|
||||||
|
# 如果不归零,那么在反向传播时,计算出来的偏导会累加在原先的偏导上,
|
||||||
|
# 造成错误。
|
||||||
|
optimizer.zero_grad()
|
||||||
|
# 完成反向传播,更新参数
|
||||||
|
##################### please finish the code ########################
|
||||||
|
# 反向传播 (一行代码)
|
||||||
|
loss.backward()
|
||||||
|
# 更新参数 (一行代码)
|
||||||
|
optimizer.step()
|
||||||
|
################################ end ################################
|
||||||
|
total_loss += loss.item()
|
||||||
|
count += 1
|
||||||
|
total_tp += get_tp(preds,labels)
|
||||||
|
total_tn += get_tn(preds,labels)
|
||||||
|
total_fp += get_fp(preds,labels)
|
||||||
|
total_fn += get_fn(preds,labels)
|
||||||
|
Precision_ratio=total_tp/(total_tp+total_fp+1e-5)
|
||||||
|
Recall_ratio=total_tp/(total_tp+total_fn+1e-5)
|
||||||
|
F_Measure=2*(Precision_ratio*Recall_ratio)/(Precision_ratio+Recall_ratio+1e-5)
|
||||||
|
print("epoch:", epoch,
|
||||||
|
"\ncorrect times:", (total_tp+total_tn), f"training accuracy:", "%.3f" %((total_tp+total_tn)/(total_tp+total_tn+total_fp+total_fn+1e-5)*100), "%",
|
||||||
|
"\ntrue positive times:", (total_tp), f"Precision ratio:", "%.3f" %(Precision_ratio*100), "%",
|
||||||
|
f"Recall ratio:", "%.3f" %(Recall_ratio*100), "%",
|
||||||
|
f"F-Measure:", "%.3f" %(F_Measure*100), "%",
|
||||||
|
"\naverage_loss:", "%.3f" %(total_loss/count))
|
||||||
|
preds = network(images)
|
||||||
|
pred_list=(pred_to_label(preds)-0.5*labels).tolist()
|
||||||
|
Preds=preds.tolist()
|
||||||
|
for i in range(len(Preds)):
|
||||||
|
print("({:.5f},{})".format(Preds[i][0],pred_list[i][0]),end='')
|
||||||
|
print('\n')
|
||||||
|
total_loss = 0
|
||||||
|
total_tp = 0
|
||||||
|
total_tn = 0
|
||||||
|
total_fp = 0
|
||||||
|
total_fn = 0
|
||||||
|
count = 0
|
||||||
|
for batch in val_loader:
|
||||||
|
images, labels = batch
|
||||||
|
preds = network(images)
|
||||||
|
loss = loss_func(preds, labels)
|
||||||
|
total_loss += loss.item()
|
||||||
|
count += 1
|
||||||
|
total_tp += get_tp(preds,labels)
|
||||||
|
total_tn += get_tn(preds,labels)
|
||||||
|
total_fp += get_fp(preds,labels)
|
||||||
|
total_fn += get_fn(preds,labels)
|
||||||
|
print("\nOn val:",
|
||||||
|
"\ncorrect times:", (total_tp+total_tn), f"training accuracy:", "%.3f" %((total_tp+total_tn)/(total_tp+total_tn+total_fp+total_fn+1e-5)*100), "%",
|
||||||
|
"\ntrue positive times:", (total_tp), f"Precision ratio:", "%.3f" %(total_tp/(total_tp+total_fp+1e-5)*100), "%",
|
||||||
|
f"Recall ratio:", "%.3f" %(total_tp/(total_tp+total_fn+1e-5)*100), "%",
|
||||||
|
f"F-Measure:", "%.3f" %(F_Measure*100), "%",
|
||||||
|
"\naverage_loss:", "%.3f" %(total_loss/count))
|
||||||
|
preds=network(images)
|
||||||
|
print("output avg:",torch.mean(preds).item(),"output std:",torch.std(preds).item())
|
||||||
|
torch.save(network, "Dev_netv1.0_CNN.pth") # PATH variable should be stated
|
Loading…
Reference in New Issue