Skip to content

Commit

Permalink
Merge pull request #2 from lalala199812138/master
Browse files Browse the repository at this point in the history
Add files via upload
  • Loading branch information
qzcool authored Jun 29, 2020
2 parents cfe1b91 + 17b6c57 commit baf8834
Show file tree
Hide file tree
Showing 5 changed files with 407 additions and 0 deletions.
46 changes: 46 additions & 0 deletions AirtableDataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# %%
from airtable import Airtable
import pandas as pd

base_id = 'app5x8nFdXg0Jj9JY'
table_name = '评分'
api_key = 'keyFvA03TJKPauBhh'

AT = Airtable(base_id, table_name, api_key)
print(AT)

# %%
view_name = 'Grid view'
records = AT.get_all(view=view_name)

df = pd.DataFrame.from_records((r['fields'] for r in records))
photos = df['房源照片']
ranks = df['平均评分']

# %%
import requests

def get_image(url, pic_name):
response = requests.get(url)
with open(pic_name, "wb") as fp:
for data in response.iter_content(128):
fp.write(data)

# %%
s = len(photos)
for i in range(s):
pic_name = './data/%04d.png'%i
url = photos[i][0]['url']
get_image(url, pic_name)

# %%
with open('./data/label.txt', "w") as fopen:
for i in range(s):
pic_name = './data/%04d.png'%i
fopen.write(pic_name)
fopen.write('\t')
fopen.write(str(ranks[i]))
fopen.write('\n')


# %%
25 changes: 25 additions & 0 deletions ResizePic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# %%
import cv2

src = cv2.imread('F:/rangduju/cnn-classification/data/0000.png', cv2.IMREAD_UNCHANGED)
sw, sh, channels = src.shape
dw = int(sw/5)
dh = int(sh/5)
#inter = cv2.INTER_LINEAR
# 双线性插值。速度为最近邻和双三次的适中,效果也为二者适中。
inter = cv2.INTER_AREA
# 区域插值,共分三种情况。图像放大时类似于双线性插值,图像缩小(x轴、y轴同时缩小)又分两种情况,均可避免波纹出现。
#inter = cv2.INTER_LANCZOS4
# 兰索斯插值。8*8,公式类似于双线性,计算量更大,效果更好,速度较慢。
#iner = cv2.INTER_NEAREST
# 最近邻插值。因为没有插值,所以边缘会有严重的锯齿,放大后的图像有很严重的马赛克,缩小后的图像有很严重的失真。
#inter = cv2.INTER_CUBIC
# 双三次插值。有效地避免出现锯齿现象,但速度最慢。放大时效果最好,但速度很慢。实际测试中并不慢,可能是优化的原因。

#dst = cv2.resize(src, (d_h, d_w), interpolation=inter)
dst = cv2.resize(src, (0,0), fx=0.2, fy=0.2, interpolation=inter)
cv2.imshow("dst",dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# area插值效果最好,5种算法中只有area可以看清车牌并且没有车牌边缘没有出现波纹,其他都多少出现扭曲。
# %%
110 changes: 110 additions & 0 deletions cnn_classification.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#%%
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms, models

#%%
torch.manual_seed(53113)

use_cuda = torch.cuda.is_available()
device = torch.device("cuda" if use_cuda else "cpu")
batch_size = test_batch_size =32
kwargs = {'num_workers':0, 'pin_memory':True} if use_cuda else{}

#%%
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('./mnist_data', train=True, download=False,
transform=transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.1307,),(0.3081,))])),
batch_size=batch_size, shuffle=True,**kwargs
)


test_loader = torch.utils.data.DataLoader(
datasets.MNIST('./mnist_data', train=False, download=False,
transform=transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))])),
batch_size=test_batch_size,
shuffle=True, **kwargs
)

#%%
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5, 1)
self.conv2 = nn.Conv2d(20, 50, 5, 1)
self.fc1 = nn.Linear(4*4*50, 500)
self.fc2 = nn.Linear(500, 10)

def forward(self, x):
x = F.relu(self.conv1(x))
x = F.max_pool2d(x, 2, 2)
x = F.relu(self.conv2(x))
x = F.max_pool2d(x, 2, 2)
x = x.view(-1, 4*4*50)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return F.log_softmax(x, dim=1)
# forward和__init__要对齐,NotImplementedError是没有检测到forward
# %%
lr = 1e-3
momentum = 0.5
model = Net().to(device)
optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)

#%%
def train(model, device, train_loader, optimizer, epoch, log_interval=100):
model.train()
for batch_idx,(data,target) in enumerate(train_loader):
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data)
loss = F.nll_loss(output, target)

loss.backward()
optimizer.step()
if batch_idx % log_interval ==0:
print("Train Epoch:{} [{}/{} ({:0f}%)]\tLoss:{:.6f}".format(
epoch,
batch_idx * len(data),
len(train_loader.dataset),
100.*batch_idx/len(train_loader),
loss.item()
))

#%%
def test(model, devivce, test_loader):
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for data, target in test_loader:
data, target = data.to(devivce), target.to(devivce)
output = model(data)
test_loss +=F.nll_loss(output, target, reduction='sum').item()

pred = output.argmax(dim=1, keepdim=True)
correct +=pred.eq(target.view_as(pred)).sum().item()

test_loss /= len(test_loader.dataset)
print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))

# %%
epochs = 2
for epoch in range(1, epochs + 1):
train(model, device, train_loader, optimizer, epoch)
test(model, device, test_loader)

save_model = True
if (save_model):
torch.save(model.state_dict(),"mnist_cnn.pt")
#词典格式,model.state_dict()只保存模型参数

# %%
209 changes: 209 additions & 0 deletions cnn_transfer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
#%%
import numpy as np
import torch
import torchvision
import torch.nn as nn
from torchvision import datasets, transforms, models
import cv2

import matplotlib.pyplot as plt
import time
import os
import copy
print("Torchvision Version: ",torchvision.__version__)

# %%
# Top level data directory. Here we assume the format of the directory conforms
# to the ImageFolder structure
data_dir = "./hymenoptera_data"
# Models to choose from [resnet, alexnet, vgg, squeezenet, densenet, inception]
model_name = "resnet"
# model_name = "alexnet"
# model_name = "vgg"
# Number of classes in the dataset
num_classes = 2
# Batch size for training (change depending on how much memory you have)
batch_size = 32
# Number of epochs to train for
num_epochs = 15
# Flag for feature extracting. When False, we finetune the whole model,
# when True we only update the reshaped layer params
feature_extract = True

input_size = 224

# %%
all_imgs = datasets.ImageFolder(os.path.join(data_dir, "train"), transforms.Compose([
transforms.RandomResizedCrop(input_size),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
]))
loader = torch.utils.data.DataLoader(all_imgs,
batch_size=batch_size,
shuffle=True,
num_workers=4)

# %%
data_transforms = {
"train": transforms.Compose([
transforms.RandomResizedCrop(input_size),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
"val": transforms.Compose([
transforms.Resize(input_size),
transforms.CenterCrop(input_size),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
}

image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ["train", "val"]}

dataloaders_dict = {x: torch.utils.data.DataLoader(image_datasets[x],
batch_size=batch_size, shuffle=True, num_workers=0) for x in ["train", "val"]}

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# %%
img = next(iter(dataloaders_dict["val"]))[0]
print(img.shape)

# %%
'''
unloader = transforms.ToPILImage() # reconvert into PIL image
plt.ion()
def imshow(tensor, title=None):
image = tensor.cpu().clone() # we clone the tensor to not do changes on it
image = image.squeeze(0) # remove the fake batch dimension
image = unloader(image)
plt.imshow(image)
if title is not None:
plt.title(title)
plt.pause(0.001) # pause a bit so that plots are updated
plt.figure()
imshow(img[11], title='Image')
'''

# %%
def set_parameter_requires_grad(model, feature_extract):
if feature_extract:
for param in model.parameters():
param.requires_grad = False

def initialize_model(model_name, num_classes, feature_extract, use_pretrained=True):
if model_name == "resnet":
model_ft = models.resnet18(pretrained=use_pretrained)
set_parameter_requires_grad(model_ft, feature_extract)
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs, num_classes)
input_size = 224

elif model_name == "alexnet":
model_ft = models.alexnet(pretrained=use_pretrained)
set_parameter_requires_grad(model_ft, feature_extract)
s = len(model_ft.classifier) - 1
num_ftrs = model_ft.classifier[s].in_features
model_ft.classifier[s] = nn.Linear(num_ftrs, num_classes)
input_size = 224

elif model_name == "vgg":
model_ft = models.vgg19_bn()
set_parameter_requires_grad(model_ft, feature_extract)
s = len(model_ft.classifier) - 1
num_ftrs = model_ft.classifier[s].in_features
model_ft.classifier[s] = nn.Linear(num_ftrs, num_classes)
input_size = 224

else:
print("model not implemented")
return None, None

return model_ft, input_size

model_ft, input_size = initialize_model(model_name,
num_classes, feature_extract, use_pretrained=True)
print(model_ft)

# %%
def train_model(model, dataloaders, loss_fn, optimizer, num_epochs=5):
best_model_wts = copy.deepcopy(model.state_dict())
best_acc = 0.
val_acc_history = []
for epoch in range(num_epochs):
for phase in ["train", "val"]:
running_loss = 0.
running_corrects = 0.
if phase == "train":
model.train()
else:
model.eval()

for inputs, labels in dataloaders[phase]:
inputs, labels = inputs.to(device), labels.to(device)

with torch.autograd.set_grad_enabled(phase=="train"):
outputs = model(inputs) # bsize * 2
loss = loss_fn(outputs, labels)

preds = outputs.argmax(dim=1)
if phase == "train":
optimizer.zero_grad()
loss.backward()
optimizer.step()
running_loss += loss.item() * inputs.size(0)
running_corrects += torch.sum(preds.view(-1) == labels.view(-1)).item()

epoch_loss = running_loss / len(dataloaders[phase].dataset)
epoch_acc = running_corrects / len(dataloaders[phase].dataset)

print("Phase {} loss: {}, acc: {}".format(phase, epoch_loss, epoch_acc))

if phase == "val" and epoch_acc > best_acc:
best_acc = epoch_acc
best_model_wts = copy.deepcopy(model.state_dict())
if phase == "val":
val_acc_history.append(epoch_acc)
model.load_state_dict(best_model_wts)
return model, val_acc_history

# %%
model_ft = model_ft.to(device)
optimizer = torch.optim.SGD(filter(lambda p: p.requires_grad,
model_ft.parameters()), lr=0.001, momentum=0.9)
loss_fn = nn.CrossEntropyLoss()
# %%
_, ohist = train_model(model_ft, dataloaders_dict, loss_fn, optimizer, num_epochs=num_epochs)

# %%
model_scratch, _ = initialize_model(model_name,
num_classes, feature_extract=False, use_pretrained=False)
model_scratch = model_scratch.to(device)
optimizer = torch.optim.SGD(filter(lambda p: p.requires_grad,
model_scratch.parameters()), lr=0.001, momentum=0.9)
loss_fn = nn.CrossEntropyLoss()
_, scratch_hist = train_model(model_scratch, dataloaders_dict, loss_fn, optimizer, num_epochs=num_epochs)

save_model = True
if (save_model):
torch.save(model_scratch.state_dict(),"cnn_transfer.pt")
# %%
# Plot the training curves of validation accuracy vs. number
# of training epochs for the transfer learning method and
# the model trained from scratch

plt.figure()
plt.title("Validation Accuracy vs. Number of Training Epochs")
plt.xlabel("Training Epochs")
plt.ylabel("Validation Accuracy")
plt.plot(range(1,num_epochs+1),ohist,label="Pretrained")
plt.plot(range(1,num_epochs+1),scratch_hist,label="Scratch")
plt.ylim((0,1.))
plt.xticks(np.arange(1, num_epochs+1, 1.0))
plt.legend()
plt.show()
Loading

0 comments on commit baf8834

Please sign in to comment.