比赛链接传送门:零基础入门CV - 街景字符编码识别-天池大赛-阿里云天池
该比赛以SVHN街道字符为赛题数据,数据集报名后可见并可下载,该数据来自收集的SVHN街道字符,并进行了匿名采样处理,详细的介绍见赛事官网 。
首先看它们的数据组成以及特点,链接比赛里面的论坛的Task1-5是对这个比赛大致的讲解,大家可以先去看看。总的来说,train是3W张,val是1W张,test是4W张。里面都是数字,有1个,2个…6个数字组成,你要把它们识别出来,以准确率为衡量标准 。
我们要做的就是识别图片中的数字串,赛题给定的数据图片中不同图片中包含的字符数量不等
首先得报名,报了名才可以下载数据集。在这里下载
https://tianchi.aliyun.com/competition/entrance/531795/information,图片放不上来。就放网站吧。
网上说这个代码可以下载,不过我没试。
import pandas as pd
import os
import requests
import zipfile
import shutil
links = pd.read_csv('/content/mchar_data_list_0515.csv')
dir_name = 'NDataset'
mypath = '/content/'
if not os.path.exists(mypath + dir_name):
os.mkdir(mypath + dir_name)
for i,link in enumerate(links['link']):
file_name = links['file'][i]
print(file_name, '\t', link)
file_name = mypath + dir_name + '/' + file_name
if not os.path.exists(file_name):
response = requests.get(link, stream=True)
with open( file_name, 'wb') as f:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
zip_list = ['mchar_train', 'mchar_test_a', 'mchar_val']
for little_zip in zip_list:
if not os.path.exists(mypath + dir_name + '/' + little_zip):
zip_file = zipfile.ZipFile(mypath + dir_name + '/' + little_zip + '.zip', 'r')
zip_file.extractall(path = mypath + dir_name )
if os.path.exists(mypath + dir_name + '/' + '__MACOSX'):
shutil.rmtree(mypath + dir_name + '/' + '__MACOSX')
links就是刚刚下载的文件,改成你们本地相对位置就好了,然后就执行,无脑等待 , 执行完之后就会有如下东西,
传送门:Datawhale 零基础入门CV赛事-Baseline-天池实验室-实时在线的数据分析协作工具,享受免费计算资源
这个代码是官方给的baseline顺利执行完,结果应该能达到0.52左右,想要高分当然需要自己做修改,不然这个比赛就没意义了。
因为是小白,刚开始接触,于是就把代码复制过来运行,但是会有报错 **RuntimeError: Expected object of scalar type Long but got scalar type Int for argument #2 ‘target’ in call to _thnn_nll_loss_forward” **
于是我就在网上查找,说加个 target=target.long()
一开始我随便加了个地方报错: local variable ‘target’ referenced before assignment
意思是说:赋值之前引用的局部变量,于是我就把放在了赋值之后。运行成功!顺便说一句,我的电脑不太好,跑的时间挺长,我还以为还会报错,等了一会就去睡午觉了,起来一看竟然成功了。
下面给上训练修改部分的代码。
def train(train_loader, model, criterion, optimizer, epoch):
# 切换模型为训练模式
model.train()
train_loss = []
for i, (input, target) in enumerate(train_loader):
if use_cuda:
input = input.cuda()
target = target.long()
target = target.cuda()
c0, c1, c2, c3, c4 = model(input)
loss = criterion(c0, target[:, 0]) + \
criterion(c1, target[:, 1]) + \
criterion(c2, target[:, 2]) + \
criterion(c3, target[:, 3]) + \
criterion(c4, target[:, 4])
# loss /= 6
optimizer.zero_grad()
loss.backward()
optimizer.step()
train_loss.append(loss.item())
return np.mean(train_loss)
def validate(val_loader, model, criterion):
# 切换模型为预测模型
model.eval()
val_loss = []
# 不记录模型梯度信息
with torch.no_grad():
for i, (input, target) in enumerate(val_loader):
if use_cuda:
input = input.cuda()
target = target.long()
target = target.cuda()
c0, c1, c2, c3, c4 = model(input)
loss = criterion(c0, target[:, 0]) + \
criterion(c1, target[:, 1]) + \
criterion(c2, target[:, 2]) + \
criterion(c3, target[:, 3]) + \
criterion(c4, target[:, 4])
# loss /= 6
val_loss.append(loss.item())
return np.mean(val_loss)
def predict(test_loader, model, tta=10):
model.eval()
test_pred_tta = None
# TTA 次数
for _ in range(tta):
test_pred = []
with torch.no_grad():
for i, (input, target) in enumerate(test_loader):
if use_cuda:
input = input.cuda()
c0, c1, c2, c3, c4 = model(input)
if use_cuda:
output = np.concatenate([
c0.data.cpu().numpy(),
c1.data.cpu().numpy(),
c2.data.cpu().numpy(),
c3.data.cpu().numpy(),
c4.data.cpu().numpy()], axis=1)
else:
output = np.concatenate([
c0.data.numpy(),
c1.data.numpy(),
c2.data.numpy(),
c3.data.numpy(),
c4.data.numpy()], axis=1)
test_pred.append(output)
test_pred = np.vstack(test_pred)
if test_pred_tta is None:
test_pred_tta = test_pred
else:
test_pred_tta += test_pred
return test_pred_tta
在之后就是测试训练了,注意要把**test_json = json.load(open(’…/input/test_a.json’))**这行代码注释掉,因为这是测试集的json文件。
运行测试代码,提交。