赞
踩
Downloading: "https://download.pytorch.org/models/resnet18-5c106cde.pth" to /root/.cache/torch/checkpoints/resnet18-5c106cde.pth --------------------------------------------------------------------------- gaierror Traceback (most recent call last) /opt/conda/lib/python3.7/urllib/request.py in do_open(self, http_class, req, **http_conn_args) 1318 h.request(req.get_method(), req.selector, req.data, headers, -> 1319 encode_chunked=req.has_header('Transfer-encoding')) 1320 except OSError as err: # timeout error /opt/conda/lib/python3.7/http/client.py in request(self, method, url, body, headers, encode_chunked) 1251 """Send a complete request to the server.""" -> 1252 self._send_request(method, url, body, headers, encode_chunked) 1253 /opt/conda/lib/python3.7/http/client.py in _send_request(self, method, url, body, headers, encode_chunked) 1297 body = _encode(body, 'body') -> 1298 self.endheaders(body, encode_chunked=encode_chunked) 1299 /opt/conda/lib/python3.7/http/client.py in endheaders(self, message_body, encode_chunked) 1246 raise CannotSendHeader() -> 1247 self._send_output(message_body, encode_chunked=encode_chunked) 1248 /opt/conda/lib/python3.7/http/client.py in _send_output(self, message_body, encode_chunked) 1025 del self._buffer[:] -> 1026 self.send(msg) 1027 /opt/conda/lib/python3.7/http/client.py in send(self, data) 965 if self.auto_open: --> 966 self.connect() 967 else: /opt/conda/lib/python3.7/http/client.py in connect(self) 1413 -> 1414 super().connect() 1415 /opt/conda/lib/python3.7/http/client.py in connect(self) 937 self.sock = self._create_connection( --> 938 (self.host,self.port), self.timeout, self.source_address) 939 self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) /opt/conda/lib/python3.7/socket.py in create_connection(address, timeout, source_address) 706 err = None --> 707 for res in getaddrinfo(host, port, 0, SOCK_STREAM): 708 af, socktype, proto, canonname, sa = res /opt/conda/lib/python3.7/socket.py in getaddrinfo(host, port, family, type, proto, flags) 751 addrlist = [] --> 752 for res in _socket.getaddrinfo(host, port, family, type, proto, flags): 753 af, socktype, proto, canonname, sa = res gaierror: [Errno -3] Temporary failure in name resolution During handling of the above exception, another exception occurred: URLError Traceback (most recent call last) <ipython-input-11-44a5c923ed92> in <module> ----> 1 model = SVHN_Model1() 2 criterion = nn.CrossEntropyLoss() 3 optimizer = torch.optim.Adam(model.parameters(), 0.001) 4 best_loss = 1000.0 5 <ipython-input-9-b338cca963a6> in __init__(self) 3 super(SVHN_Model1, self).__init__() 4 ----> 5 model_conv = models.resnet18(pretrained=True) 6 model_conv.avgpool = nn.AdaptiveAvgPool2d(1) 7 model_conv = nn.Sequential(*list(model_conv.children())[:-1]) /opt/conda/lib/python3.7/site-packages/torchvision/models/resnet.py in resnet18(pretrained, progress, **kwargs) 239 """ 240 return _resnet('resnet18', BasicBlock, [2, 2, 2, 2], pretrained, progress, --> 241 **kwargs) 242 243 /opt/conda/lib/python3.7/site-packages/torchvision/models/resnet.py in _resnet(arch, block, layers, pretrained, progress, **kwargs) 225 if pretrained: 226 state_dict = load_state_dict_from_url(model_urls[arch], --> 227 progress=progress) 228 model.load_state_dict(state_dict) 229 return model /opt/conda/lib/python3.7/site-packages/torch/hub.py in load_state_dict_from_url(url, model_dir, map_location, progress, check_hash) 493 sys.stderr.write('Downloading: "{}" to {}\n'.format(url, cached_file)) 494 hash_prefix = HASH_REGEX.search(filename).group(1) if check_hash else None --> 495 download_url_to_file(url, cached_file, hash_prefix, progress=progress) 496 497 # Note: extractall() defaults to overwrite file if exists. No need to clean up beforehand. /opt/conda/lib/python3.7/site-packages/torch/hub.py in download_url_to_file(url, dst, hash_prefix, progress) 392 # We use a different API for python2 since urllib(2) doesn't recognize the CA 393 # certificates in older Python --> 394 u = urlopen(url) 395 meta = u.info() 396 if hasattr(meta, 'getheaders'): /opt/conda/lib/python3.7/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context) 220 else: 221 opener = _opener --> 222 return opener.open(url, data, timeout) 223 224 def install_opener(opener): /opt/conda/lib/python3.7/urllib/request.py in open(self, fullurl, data, timeout) 523 req = meth(req) 524 --> 525 response = self._open(req, data) 526 527 # post-process response /opt/conda/lib/python3.7/urllib/request.py in _open(self, req, data) 541 protocol = req.type 542 result = self._call_chain(self.handle_open, protocol, protocol + --> 543 '_open', req) 544 if result: 545 return result /opt/conda/lib/python3.7/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args) 501 for handler in handlers: 502 func = getattr(handler, meth_name) --> 503 result = func(*args) 504 if result is not None: 505 return result /opt/conda/lib/python3.7/urllib/request.py in https_open(self, req) 1360 def https_open(self, req): 1361 return self.do_open(http.client.HTTPSConnection, req, -> 1362 context=self._context, check_hostname=self._check_hostname) 1363 1364 https_request = AbstractHTTPHandler.do_request_ /opt/conda/lib/python3.7/urllib/request.py in do_open(self, http_class, req, **http_conn_args) 1319 encode_chunked=req.has_header('Transfer-encoding')) 1320 except OSError as err: # timeout error -> 1321 raise URLError(err) 1322 r = h.getresponse() 1323 except: URLError: <urlopen error [Errno -3] Temporary failure in name resolution>
这是是因为代码会去远端下载模型的参数,而国内的网一般连接不上,这是我们需要手动去下载你要的预训练网络。对于这种情况,我选择直接从它给的路径https://download.pytorch.org/models/resnet18-5c106cde.pth下载,但是一定要注意把前面的https://去掉,就可下载。还有另外一种方式下在就是去GitHub的pytorch开源项目根据”/root/.cache/torch/checkpoints/resnet18-5c106cde.pth“这一段提示进行查找也可以下载保存。
接下来问题是什么是.pth文件,这第一次遇见。
“有时候我们正在修改或调试的程序会是一个库,为修改方便,我们可能不大希望把它放到 site-packages 下面,而是更愿意把它保留在原始的工程目录中,以方便 IDE 和版本控制工具进行管理。那么怎么能让 Python 运行环境找到这个库呢?
原理上, Python 运行环境查找库文件时本质是对 sys.path 列表的遍历,如果我们想给运行环境注册新的类库进来,要么得用代码给 sys.path 列表增加新路径;要么得调整 PYTHONPATH 环境变量;要么就得把库文件复制到已经在 sys.path 设置中的路径中去(比如 site-packages 目录);这些方法都不够方便。最简单的办法是用 .pth 文件来实现。Python 在遍历已知的库文件目录过程中,如果见到一个 .pth 文件,就会将文件中所记录的路径加入到 sys.path 设置中,于是 .pth 文件说指明的库也就可以被 Python 运行环境找到了。其实,easy_install 所依赖的 egg 包安装就是靠 site-packages 目录下的 .pth 文件添加对 egg 包的引用实现的。所以修改对应的 .pth 文件内容,就可以实现对 egg 包的卸载。”
在机器学习模型(特别是深度学习模型)的训练过程中,模型是非常容易过拟合的。深度学习模型在不断的训练过程中训练误差会逐渐降低,但测试误差的走势则不一定。
在模型的训练过程中,模型只能利用训练数据来进行训练,模型并不能接触到测试集上的样本。因此模型如果将训练集学的过好,模型就会记住训练样本的细节,导致模型在测试集的泛化效果较差,这种现象称为过拟合(Overfitting)。与过拟合相对应的是欠拟合(Underfitting),即模型在训练集上的拟合效果较差。
如图所示:随着模型复杂度和模型训练轮数的增加,CNN模型在训练集上的误差会降低,但在测试集上的误差会逐渐降低,然后逐渐升高,而我们为了追求的是模型在测试集上的精度越高越好。
导致模型过拟合的情况有很多种原因,其中最为常见的情况是模型复杂度(Model Complexity )太高,导致模型学习到了训练数据的方方面面,学习到了一些细枝末节的规律。
解决上述问题最好的解决方法:构建一个与测试集尽可能分布一致的样本集(可称为验证集),在训练过程中不断验证模型在验证集上的精度,并以此控制模型的训练。
在给定赛题后,赛题方会给定训练集和测试集两部分数据。参赛者需要在训练集上面构建模型,并在测试集上面验证模型的泛化能力。因此参赛者可以通过提交模型对测试集的预测结果,来验证自己模型的泛化能力。同时参赛方也会限制一些提交的次数限制,以此避免参赛选手“刷分”。
在一般情况下,参赛选手也可以自己在本地划分出一个验证集出来,进行本地验证。训练集、验证集和测试集分别有不同的作用:
因为训练集和验证集是分开的,所以模型在验证集上面的精度在一定程度上可以反映模型的泛化能力。在划分验证集的时候,需要注意验证集的分布应该与测试集尽量保持一致,不然模型在验证集上的精度就失去了指导意义。
既然验证集这么重要,那么如何划分本地验证集呢。在一些比赛中,赛题方会给定验证集;如果赛题方没有给定验证集,那么参赛选手就需要从训练集中拆分一部分得到验证集。验证集的划分有如下几种方式:
直接将训练集划分成两部分,新的训练集和验证集。这种划分方式的优点是最为直接简单;缺点是只得到了一份验证集,有可能导致模型在验证集上过拟合。留出法应用场景是数据量比较大的情况。
将训练集划分成K份,将其中的K-1份作为训练集,剩余的1份作为验证集,循环K训练。这种划分方式是所有的训练集都是验证集,最终模型验证精度是K份平均得到。这种方式的优点是验证集精度比较可靠,训练K次可以得到K个有多样性差异的模型;CV验证的缺点是需要训练K次,不适合数据量很大的情况。
通过有放回的采样方式得到新的训练集和验证集,每次的训练集和验证集都是有区别的。这种划分方式一般适用于数据量较小的情况。
在本次赛题中已经划分为验证集,因此选手可以直接使用训练集进行训练,并使用验证集进行验证精度(当然你也可以合并训练集和验证集,自行划分验证集)。
当然这些划分方法是从数据划分方式的角度来讲的,在现有的数据比赛中一般采用的划分方法是留出法和交叉验证法。如果数据量比较大,留出法还是比较合适的。当然任何的验证集的划分得到的验证集都是要保证训练集-验证集-测试集的分布是一致的,所以如果不管划分何种的划分方式都是需要注意的。
这里的分布一般指的是与标签相关的统计分布,比如在分类任务中“分布”指的是标签的类别分布,训练集-验证集-测试集的类别分布情况应该大体一致;如果标签是带有时序信息,则验证集和测试集的时间间隔应该保持一致。
在本节我们目标使用Pytorch来完成CNN的训练和验证过程,CNN网络结构与之前的章节中保持一致。我们需要完成的逻辑结构如下:
train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=10, shuffle=True, num_workers=10, ) val_loader = torch.utils.data.DataLoader( val_dataset, batch_size=10, shuffle=False, num_workers=10, ) model = SVHN_Model1() criterion = nn.CrossEntropyLoss (size_average=False) optimizer = torch.optim.Adam(model.parameters(), 0.001) best_loss = 1000.0 for epoch in range(20): print('Epoch: ', epoch) train(train_loader, model, criterion, optimizer, epoch) val_loss = validate(val_loader, model, criterion) # 记录下验证集精度 if val_loss < best_loss: best_loss = val_loss torch.save(model.state_dict(), './model.pt')
其中每个Epoch的训练代码如下:
def train(train_loader, model, criterion, optimizer, epoch): # 切换模型为训练模式 model.train() for i, (input, target) in enumerate(train_loader): c0, c1, c2, c3, c4, c5 = model(data[0]) loss = criterion(c0, data[1][:, 0]) + \ criterion(c1, data[1][:, 1]) + \ criterion(c2, data[1][:, 2]) + \ criterion(c3, data[1][:, 3]) + \ criterion(c4, data[1][:, 4]) + \ criterion(c5, data[1][:, 5]) loss /= 6 optimizer.zero_grad() loss.backward() optimizer.step()
其中每个Epoch的验证代码如下:
def validate(val_loader, model, criterion): # 切换模型为预测模型 model.eval() val_loss = [] # 不记录模型梯度信息 with torch.no_grad(): for i, (input, target) in enumerate(val_loader): c0, c1, c2, c3, c4, c5 = model(data[0]) loss = criterion(c0, data[1][:, 0]) + \ criterion(c1, data[1][:, 1]) + \ criterion(c2, data[1][:, 2]) + \ criterion(c3, data[1][:, 3]) + \ criterion(c4, data[1][:, 4]) + \ criterion(c5, data[1][:, 5]) loss /= 6 val_loss.append(loss.item()) return np.mean(val_loss)
在Pytorch中模型的保存和加载非常简单,比较常见的做法是保存和加载模型参数:
torch.save(model_object.state_dict(), 'model.pt')
model.load_state_dict(torch.load(' model.pt'))
深度学习原理少但实践性非常强,基本上很多的模型的验证只能通过训练来完成。同时深度学习有众多的网络结构和超参数,因此需要反复尝试。训练深度学习模型需要GPU的硬件支持,也需要较多的训练时间,如何有效的训练深度学习模型逐渐成为了一门学问。
深度学习有众多的训练技巧,比较推荐的阅读链接有:
本节挑选了常见的一些技巧来讲解,并针对本次赛题进行具体分析。与传统的机器学习模型不同,深度学习模型的精度与模型的复杂度、数据量、正则化、数据扩增等因素直接相关。所以当深度学习模型处于不同的阶段(欠拟合、过拟合和完美拟合)的情况下,大家可以知道可以什么角度来继续优化模型。
“python中的文件”:https://blog.csdn.net/weixin_42247031/article/details/101561547?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-25.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-25.nonecase
DataWhale
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。