Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python CTC损失下降并停止_Python_Neural Network_Computer Vision_Deep Learning_Pytorch - Fatal编程技术网

Python CTC损失下降并停止

Python CTC损失下降并停止,python,neural-network,computer-vision,deep-learning,pytorch,Python,Neural Network,Computer Vision,Deep Learning,Pytorch,我正在训练验证码识别模型。模型细节为resnet预训练CNN层+双向LSTM+完全连接。python库生成的验证码序列准确率达到90%。问题是,这些生成的验证码似乎具有每个字符的相似位置。当我在字符之间随机添加空格时,该模型不再工作。所以我想知道LSTM是在学习过程中学习分段的吗?然后我尝试使用CTC损失。起初,损失很快就减少了。但它保持在16左右,之后没有明显下降。我尝试了不同层次的LSTM,不同数量的单位。2层LSTM达到较低的损耗,但仍不收敛。3层就像2层。损失曲线: #编码:utf8

我正在训练验证码识别模型。模型细节为resnet预训练CNN层+双向LSTM+完全连接。python库生成的验证码序列准确率达到90%。问题是,这些生成的验证码似乎具有每个字符的相似位置。当我在字符之间随机添加空格时,该模型不再工作。所以我想知道LSTM是在学习过程中学习分段的吗?然后我尝试使用CTC损失。起初,损失很快就减少了。但它保持在16左右,之后没有明显下降。我尝试了不同层次的LSTM,不同数量的单位。2层LSTM达到较低的损耗,但仍不收敛。3层就像2层。损失曲线:

#编码:utf8
导入操作系统
导入系统
进口火炬
进口整经机
导入回溯
进口火炬视觉
来自torch import nn、autograd、FloatTensor、optim
从torch.nn导入功能为F
从torch.utils.data导入数据加载器
从torch.optim.lr\u计划程序导入多步骤
从tensorboard导入SummaryWriter
从pprint导入pprint
从net.utils导入解码器
从日志导入getLogger,StreamHandler
logger=getLogger(\uuuuu name\uuuuuu)
handler=StreamHandler(sys.stdout)
logger.addHandler(处理程序)
从数据集\u util.utils导入id\u到\u字符
从数据集_util.transform导入重缩放,使用规格化器
从config.config导入最大验证码长度、张力板日志路径、模型路径
类别CNN(nn.模块):
定义初始化(self,lstm\u双向=True,use\u ctc=True,*args,**kwargs):
超级(CNN,自我)。\初始值(*args,**kwargs)
model_conv=torchvision.models.resnet18(预训练=真)
对于模型参数()中的参数:
param.requires_grad=False
modules=list(model_conv.children())[:-1]#删除最后一个fc层。
对于模块[8]中的参数,参数()
param.requires_grad=True
self.resnet=nn.Sequential(*modules)#CNN,具有来自resnet作为特征提取器的固定参数
self.lstm\u输入大小=512*2*2
self.lstm\u hidden\u state\u size=512
self.lstm_num_layers=2
self.chracter\u space\u length=64
自。_lstm_双向=lstm_双向
self.\u use\u ctc=use\u ctc
如果使用ctc:
self.\u max\u captcha\u length=int(max\u captcha\u length*2)
其他:
self.\u max\u captcha\u length=max\u captcha\u length
如果lstm_是双向的:
self.lstm_hidden_state_size=self.lstm_hidden_state_size*2#因此双向lstm中一个方向的隐藏大小与普通lstm相同
self.lstm=self.lstm=nn.lstm(self.lstm_输入_大小,self.lstm_隐藏_状态_大小//2,dropout=0.5,双向=True,num_layers=self.lstm_num_layers)
其他:
self.lstm=nn.lstm(self.lstm_输入_大小,self.lstm_隐藏_状态_大小,dropout=0.5,双向=False,num_layers=self.lstm_num_layers)#dropout不适用于一层lstm
self.output_to_tag=nn.Linear(self.lstm_hidden_state_size,self.chracter_space_length)
self.tensorboard\u writer=SummaryWriter(tensorboard\u LOG\u路径)
#self.dropout_lstm=nn.dropout()
def初始隐藏状态(自身、批次大小):
如果是双向的:
self.hidden=(autograd.Variable(torch.zero((self.lstm_num_layers*2,批大小,self.lstm_hidden_state_size//2)),
autograd.Variable(torch.zero((self.lstm_num_layers*2,batch_size,self.lstm_hidden_state_size//2)))#层数,批次大小,隐藏尺寸
其他:
self.hidden=(autograd.Variable(torch.zero((self.lstm\u num\u layers,batch\u size,self.lstm\u hidden\u state\u size)),
autograd.Variable(torch.zero((self.lstm_num_layers,batch_size,self.lstm_hidden_state_size)))#层数,批次大小,隐藏尺寸
def转发(自身、图像):
'''
:参数图像:#批次大小、通道、高度、宽度
:返回:
'''
features=self.resnet(图像)#[批量大小,512,2,2]
批次大小=图像。形状[0]
features=[features.view(批量大小,-1)用于范围内的i(自身最大验证码长度)]
features=torch.stack(特性)
self.init\u隐藏\u状态(批量大小)
输出,隐藏=self.lstm(功能,self.hidden)
#输出=自退出(输出)
tag_space=self.output_to_tag(output.view(-1,output.size(2)))#[最大验证码长度*批量大小,字符空间长度]
tag\u space=tag\u space.view(self.\u max\u验证码长度,批大小,-1)
如果不是自己,请使用ctc:
tag_score=F.log_softmax(tag_space,dim=2)#[最大验证码长度,批量大小,字符空间长度]
其他:
标记分数=标记空间
返回tag_分数
def序列网络(自身、数据加载程序、评估数据加载程序=无、学习率=0.008、历元数=400):
尝试:
如果自己使用ctc:
loss\u function=warptcc\u pytorch.warp\u ctc.CTCLoss()
其他:
损失函数=nn.NLLLoss()
#optimizer=optim.SGD(过滤器(lambda p:p.requires_grad,self.parameters()),动量=0.9,lr=learning_rate)
#优化器=多步骤(优化器,里程碑=[10,15],伽马=0.5)
#optimizer=optim.Adadelta(过滤器(lambda p:p.requires_grad,self.parameters())
optimizer=optim.Adam(过滤器(lambda p:p.requires_grad,self.parameters())
self.tensorboard\u writer.add\u scalar(“学习率”,学习率)
tensorbard_全局_步长=0
如果os.path.exists(os.path.join(TENSORBOARD\u LOG\u path,“resume\u step”):
使用open(os.path.join(TENSORBOARD\u LOG\u path,“resume\u step”),“r”)作为文件处理程序:
tensorbard\u global\u step=int(file\u handler.read())+1
对于epoch_i