写点什么

不吹不黑一份代码即可进 Kaggle 排行榜!

用户头像
cv君
关注
发布于: 7 小时前
不吹不黑一份代码即可进Kaggle排行榜!

大家好,我是 cv 君,今天分享一份源码,有了这份代码,你就是一个 Kaggle 的一个图像分类赛排行榜因为这是很久以前的比赛,不知道还开不开榜,比如选择你还可以去刷 Kaggle 的 Mnist 排行榜 99.93+分以上就能进入排行榜(没记错的话)这个 Mnist,每个 AI 的选手都做过,大家可以看我专栏其他文章,是进 Mnist 排行榜的代码;


我们今天不做 Mnist 了,我们做几年前,特别著名的 cat-dog 分类!这份代码,你可以得到 99.3 以上的准确率,你想知道当时这个比赛进排行榜多少分吗?98.9!我们做了什么呢?








迁移学习 模型集成 数据增强 调优调参 优化提分 冻结网络欢迎来到动手撸深度学习~cv 君力挺的,最值得看的专栏系列:动手撸深度学习学习完本系列,你能从调包侠到一个能独立打比赛的朋友周边的神!文章付费,不想让太多人白嫖!!!因为全部原创,很珍贵!!看完你会感谢我的~感兴趣的话,就来看看吧~首先,大家通过上两节,我们已经通过 Keras 搭建了自己的神经网络,并且学习了搭建方法,数据增强方法,Dropout 等的使用方法和原理,并且学习了迁移学习的几种方式,并且实现了得到了 98.5 以上的准确率,我们距离排行榜还有一些些距离。这一节我们开始:迁移学习 模型集成 数据增强 调优调参 优化提分 冻结网络


现在来看代码:老规矩,导入库


model_resnet18 = torch.hub.load('pytorch/vision', 'resnet18', pretrained=True)model_resnet34 = torch.hub.load('pytorch/vision', 'resnet34', pretrained=True)
复制代码


for name, param in model_resnet18.named_parameters():if ("bn" not in name):param.requires_grad = False
for name, param in model_resnet34.named_parameters():if ("bn" not in name):param.requires_grad = False
训练分类器权重
复制代码


num_classes = 2
model_resnet18.fc = nn.Sequential(nn.Linear(model_resnet18.fc.in_features, 512),nn.ReLU(),nn.Dropout(),nn.Linear(512, num_classes))
model_resnet34.fc = nn.Sequential(nn.Linear(model_resnet34.fc.in_features, 512),nn.ReLU(),nn.Dropout(),nn.Linear(512, num_classes))
123456789101112定义训练
def train(model, optimizer, loss_fn, train_loader, val_loader, epochs=2, device="cpu"):for epoch in range(epochs):training_loss = 0.0valid_loss = 0.0model.train()for batch in train_loader:optimizer.zero_grad()inputs, targets = batchinputs = inputs.to(device)targets = targets.to(device)output = model(inputs)loss = loss_fn(output, targets)loss.backward()optimizer.step()training_loss += loss.data.item() * inputs.size(0)print(loss)training_loss /= len(train_loader.dataset)

复制代码


    model.eval()    num_correct = 0    num_examples = 0    for batch in val_loader:        inputs, targets = batch        inputs = inputs.to(device)        output = model(inputs)        targets = targets.to(device)        optimizer.zero_grad()
loss = loss_fn(output, targets) valid_loss += loss.data.item() * inputs.size(0)
correct = torch.eq(torch.max(F.softmax(output, dim=1), dim=1)[1], targets).view(-1) num_correct += torch.sum(correct).item() num_examples += correct.shape[0] valid_loss /= len(val_loader.dataset)
print( 'Epoch: {}, Training Loss: {:.4f}, Validation Loss: {:.4f}, accuracy = {:.4f}'.format(epoch, training_loss,
复制代码


数据读取


batch_size=40img_dimensions = 224
Normalize to the ImageNet mean and standard deviation
Could calculate it for the cats/dogs data set, but the ImageNet
values give acceptable results here.
img_transforms = transforms.Compose([transforms.Resize((img_dimensions, img_dimensions)),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])])
img_test_transforms = transforms.Compose([transforms.Resize((img_dimensions,img_dimensions)),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])])
train_data_path = "train_total/"train_data = torchvision.datasets.ImageFolder(root=train_data_path,transform=img_transforms, is_valid_file=check_image)
validation_data_path = "val_total/"validation_data = torchvision.datasets.ImageFolder(root=validation_data_path,transform=img_test_transforms, is_valid_file=check_image)
test_data_path = "val_total/"test_data = torchvision.datasets.ImageFolder(root=test_data_path, transform=img_test_transforms, is_valid_file=check_image)
num_workers = 0train_data_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, shuffle=True, num_workers=num_workers)validation_data_loader = torch.utils.data.DataLoader(validation_data, batch_size=batch_size, shuffle=False, num_workers=num_workers)test_data_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size, shuffle=False, num_workers=num_workers)

复制代码

测试


def test_model(model):correct = 0total = 0with torch.no_grad():for data in test_data_loader:images, labels = data[0].to(device), data[1].to(device)outputs = model(images)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print('correct: {:d}  total: {:d}'.format(correct, total))print('accuracy = {:f}'.format(correct / total))
复制代码

训练部分

model_resnet18.to(device)optimizer = optim.Adam(model_resnet18.parameters(), lr=0.001)train(model_resnet18, optimizer, torch.nn.CrossEntropyLoss(), train_data_loader, validation_data_loader, epochs=2, device=device)test_model(model_resnet18)
model_resnet34.to(device)optimizer = optim.Adam(model_resnet34.parameters(), lr=0.001)train(model_resnet34, optimizer, torch.nn.CrossEntropyLoss(), train_data_loader, validation_data_loader, epochs=2, device=device)test_model(model_resnet34)
torch.save(model_resnet18.state_dict(), "./models/model_resnet18.pth")torch.save(model_resnet34.state_dict(), "./models/model_resnet34.pth")

复制代码

训练完毕 可以实际验证结果啦~

resnet18 = torch.hub.load('pytorch/vision', 'resnet18')resnet18.fc = nn.Sequential(nn.Linear(resnet18.fc.in_features, 512), nn.ReLU(), nn.Dropout(), nn.Linear(512, num_classes))resnet18.load_state_dict(torch.load('./models/model_resnet18.pth'))resnet18.eval()
resnet34 = torch.hub.load('pytorch/vision', 'resnet34')resnet34.fc = nn.Sequential(nn.Linear(resnet34.fc.in_features, 512), nn.ReLU(), nn.Dropout(), nn.Linear(512, num_classes))resnet34.load_state_dict(torch.load('./models/model_resnet34.pth'))resnet34.to(device)resnet34.eval()def predict():import osdef find_classes(dir):classes = os.listdir(dir)classes.sort()class_to_idx = {classes[i]: i for i in range(len(classes))}return classes, class_to_idx

复制代码


def make_prediction(model, filename):    labels, _ = find_classes('test1/')    img = Image.open(filename)    img = img_test_transforms(img)    img = img.unsqueeze(0)    prediction = model(img.to(device))    prediction = prediction.argmax()    print(prediction)
make_prediction(model_resnet34.to(device), 'test1/14.jpg')make_prediction(model_resnet34.to(device), 'test1/10.jpg')def val():models_ensemble = [resnet18.to(device), resnet34.to(device)] correct = 0total = 0with torch.no_grad():for data in test_data_loader:images, labels = data[0].to(device), data[1].to(device)predictions = [i(images).data for i in models_ensemble]avg_predictions = torch.mean(torch.stack(predictions), dim=0)_, predicted = torch.max(avg_predictions, 1)
复制代码


        total += labels.size(0)        correct += (predicted == labels).sum().item()
print('accuracy = {:f}'.format(correct / total))print('correct: {:d} total: {:d}'.format(correct, total))val()predict()
复制代码


测试时集成模型


models_ensemble = [resnet18.to(device), resnet34.to(device)]correct = 0total = 0with torch.no_grad():for data in test_data_loader:images, labels = data[0].to(device), data[1].to(device)predictions = [i(images).data for i in models_ensemble]avg_predictions = torch.mean(torch.stack(predictions), dim=0)_, predicted = torch.max(avg_predictions, 1)
复制代码


        total += labels.size(0)        correct += (predicted == labels).sum().item()
复制代码


大家可以看到模型集成地方式,当然这只是一种集成方法


何谓模型集成即通过训练多个模型,对带预测数据进行拟合(训练时集成)和验证时集成(测试时多模型投票或者平均或者比例方式)


以上通过 10 折交叉验证,可训练得到 10 个 CNN 模型,集成方法有:


平均法:将 10 个模型预测结果的概率取平均值,然后解码为具体字符投票法:对 10 个模型预测结果进行投票,得到最终字符 12 各个代码,函数的具体意思,请看我的视频~视频很详细地介绍了。视频地址:链接:https://pan.baidu.com/s/1teabC-TIfc-8MPVcV_Q76g提取码:deep 一定要看看嗷,这里讲的清晰一些。

用户头像

cv君

关注

还未添加个人签名 2021.03.22 加入

还未添加个人简介

评论

发布
暂无评论
不吹不黑一份代码即可进Kaggle排行榜!