字符过多被剪取

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>jquery限制输入字数,并提示剩余字数</title> 
<script type="text/javascript" src="jquery.js"></script> 
<script type="text/javascript"> 
function words_deal() 

var curLength=$("#TextArea1").val().length; 
if(curLength>5) 

var num=$("#TextArea1").val().substr(0,5); 
$("#TextArea1").val(num); 
alert("超过字数限制,多出的字将被截断!" ); 

else 

$("#textCount").text(5-$("#TextArea1").val().length); 


</script> 
</head> 
<body> 
剩余<span id="textCount">5</span>个字<br /> 
<textarea name="textarea" id="TextArea1" cols="45" rows="5" onkeyup="words_deal();" ></textarea> 
</body> 
</html> 
% 定义字符集 charSet = '0123456789+-×÷= '; % 字符集,包含空格 numClasses = length(charSet) + 1; % 字符类别数 + 空白符 % === 输入地址部分 - 修正版 === % 使用绝对路径确保可靠性 dataFolder = fullfile(pwd, 'math_problems'); % 当前目录下的math_problems文件夹 % 如果路径不存在则创建 if ~exist(dataFolder, 'dir') mkdir(dataFolder); error('数据集目录不存在,已创建空目录: %s\n请将数据放入此目录', dataFolder); end % 加载图像数据集 - 修正LabelSource参数 imds = imageDatastore(dataFolder, ... 'IncludeSubfolders', true, ... 'LabelSource', 'foldernames'); % 修正为'foldernames' % === 标签处理 === % 获取文件夹名称作为类别标签 labels = imds.Labels; % 现在labels是categorical类型 % 转换为字符串数组 labelStrings = string(labels); % 创建字符到索引的映射 char2idx = containers.Map(); for i = 1:length(charSet) char2idx(charSet(i)) = i; end char2idx(' ') = length(charSet) + 1; % 空白符 % 转换标签为数字序列 labelSequences = cell(numel(labels), 1); for i = 1:numel(labels) str = char(labels(i)); seq = zeros(1, length(str)); for j = 1:length(str) seq(j) = char2idx(str(j)); end labelSequences{i} = seq; end % === 数据预处理 === preprocessFcn = @(I) preprocessImage(I); function imgProcessed = preprocessImage(I) % 转换为灰度图像 if size(I, 3) == 3 I = rgb2gray(I); end % 自动裁剪图像(去除空白边缘) I = imbinarize(I); % 二值化处理 I = imclearborder(I); stats = regionprops(I, 'BoundingBox'); if ~isempty(stats) bbox = stats(1).BoundingBox; % 取第一个连通区域 I = imcrop(I, bbox); end % 调整图像大小为固定尺寸 targetSize = [64, 320]; % 目标尺寸 imgProcessed = imresize(I, targetSize); % 归一化处理 imgProcessed = im2double(imgProcessed); end % 应用预处理 preprocessedImds = transform(imds, @(x) preprocessData(x, preprocessFcn)); function dataOut = preprocessData(dataIn, preprocessFcn) dataOut = dataIn; dataOut.Image = preprocessFcn(dataIn.Image); end % === 数据集划分 === rng(42); % 设置随机种子 numFiles = numel(imds.Files); shuffledIdx = randperm(numFiles); % 80%训练,20%验证 trainIdx = shuffledIdx(1:round(0.8*numFiles)); valIdx = shuffledIdx(round(0.8*numFiles)+1:end); % 创建训练集 trainImages = subset(preprocessedImds, trainIdx); trainLabels = labelSequences(trainIdx); % 创建验证集 valImages = subset(preprocessedImds, valIdx); valLabels = labelSequences(valIdx); % === 网络构建 === % [使用之前的动态reshape方案] % ... 此处插入前面提供的动态reshape网络代码 ... % === 训练选项 === options = trainingOptions('adam', ... 'MaxEpochs', 30, ... 'MiniBatchSize', 32, ... 'InitialLearnRate', 0.001, ... 'Shuffle', 'every-epoch', ... 'ValidationData', {valImages, valLabels}, ... % 使用定义的验证集 'ValidationFrequency', 10, ... 'Verbose', true, ... 'Plots', 'training-progress'); % 开始训练 net = trainNetwork(trainImages, trainLabels, lgraph, options); % 保存模型 save(fullfile(dataFolder, 'trainedOCRNet.mat'), 'net'); 还是刚才的问题
06-18
<think>我们之前已经解决了imageDatastore的标签源参数错误(将'folders'改为'foldernames'),现在出现的新问题是:错误使用索引此容器中不存在指定的键。出错tranorc(第40行)seq(j)=char2idx(str(j));原因:在标签字符串中出现了字符映射表(char2idx)中不存在的字符。解决方案:1.在映射前检查字符是否存在,如果不存在,则使用一个特殊标记(如空白符或未知字符)代替。2.或者,在构建字符映射表时,确保包含所有可能出现的字符。但是,我们无法预先知道所有字符,因此采用第一种方法:遇到未知字符时,将其映射到空白符(或一个特定的未知字符索引)。修改第40行附近的循环:原代码:forj=1:length(str)seq(j)=char2idx(str(j));end修改为:forj=1:length(str)ifisKey(char2idx,str(j))seq(j)=char2idx(str(j));else%映射到空白符(空格)的索引,或者可以设置一个未知字符的索引seq(j)=char2idx('');%或者使用一个特定的未知字符索引,例如:numClasses(如果空白符已经是最后一个,则这里空白符的索引是length(charSet)+1)endend注意:我们之前已经将空格的索引设置为length(charSet)+1,所以这里直接使用。但是,我们也可以专门设置一个未知字符的索引。例如,我们可以将未知字符映射到空白符,或者单独设置一个索引。建议:在字符集中显式添加一个未知字符(例如,'<UNK>')并分配索引。但是,由于我们的标签是文件夹名称,且标签字符串是数学表达式,理论上应该只包含我们定义的字符集。出现未知字符可能是文件夹命名错误。因此,我们可以采取两种方式:方式一:将未知字符替换为空格(即忽略),然后映射到空格的索引。方式二:将未知字符映射到一个新的索引(例如,numClasses+1),但这样需要修改网络输出类别数。由于我们的网络输出类别数已经固定为numClasses(即length(charSet)+1,包括空格),所以不能随意增加。因此,采用方式一:将未知字符视为空格。但是,空格在我们的字符集中已经存在,且我们将其索引设为length(charSet)+1。所以,我们只需要在遇到未知字符时,将其映射到空格的索引即可。修改代码:在循环中添加条件判断:forj=1:length(str)ifchar2idx.isKey(str(j))%检查字符是否在映射表中seq(j)=char2idx(str(j));elseseq(j)=char2idx('');%使用空格的索引%或者可以给出警告warning('发现未知字符:"%s",在标签:%s中,位置:%d。已替换为空格。',str(j),str,j);endend这样,当遇到未知字符时,程序不会报错,而是将其替换为空格,并给出警告,以便我们检查文件夹命名。另外,为了避免过多的警告,我们可以记录一次即可,或者不显示警告。但为了调试,建议显示。完整修改后的标签处理部分:%创建字符到索引的映射charSet='0123456789+-×÷=';%字符集,包含空格char2idx=containers.Map();fori=1:length(charSet)char2idx(charSet(i))=i;end%空白符已经包含在charSet中(最后一个字符是空格),所以不需要额外设置?不对,我们之前将空格单独设置了一次,但这里空格已经在charSet中,所以循环中已经设置了。%注意:上面的charSet中已经包含了空格,所以循环中已经将空格映射到索引length(charSet)(因为空格是最后一个字符,索引为length(charSet))。但是,我们之前又额外设置了一次:%char2idx('')=length(charSet)+1;%这会导致空格被重新映射到length(charSet)+1,而其他字符的索引是1到length(charSet)。这样空格就有两个索引?这是错误的。修正:去掉单独设置空格的代码,因为空格已经在charSet中。因此,修改:删除:char2idx('')=length(charSet)+1;这样,空格在循环中已经被映射到索引(length(charSet)),因为空格是charSet的最后一个字符。但是,我们之前定义charSet时,空格在最后,所以索引就是length(charSet)。因此,修改后的代码:%定义字符集charSet='0123456789+-×÷=';%注意:这里已经包含了空格%...其他代码...%创建字符到索引的映射char2idx=containers.Map();fori=1:length(charSet)char2idx(charSet(i))=i;%空格将映射到16(如果charSet长度为15,则空格是第16个?不对,注意charSet字符串的长度是15(包括空格),所以空格的位置是第15个字符,索引为15。end%因此,空格的索引是15(如果charSet的长度为15,则i从1到15,空格是最后一个,索引15)。%所以,在遇到未知字符时,我们将其映射到空格的索引15。但是,我们之前定义numClasses=length(charSet)+1;这是不对的,因为charSet已经包含了空格,所以字符类别数就是length(charSet)。所以应该改为:numClasses=length(charSet);%因为charSet已经包含所有字符,包括空格因此,需要调整numClasses的定义。总结修改步骤:1.将numClasses改为length(charSet)2.删除单独设置空格的代码(char2idx('')=...)3.在转换标签的循环中,对未知字符使用空格(即charSet中的最后一个字符)的索引。修改后的代码:%定义字符集charSet='0123456789+-×÷=';%字符集,包含空格numClasses=length(charSet);%字符类别数(包含空格)%...其他代码不变...%创建字符到索引的映射char2idx=containers.Map();fori=1:numClasseschar2idx(charSet(i))=i;end%转换标签为数字序列labelSequences=cell(numel(labels),1);fori=1:numel(labels)str=char(labels(i));seq=zeros(1,length(str));forj=1:length(str)ifisKey(char2idx,str(j))seq(j)=char2idx(str(j));else%使用空格的索引(空格在charSet中,索引为numClasses,因为空格是最后一个)seq(j)=numClasses;%或者char2idx(charSet(end))即char2idx('')%给出警告warning('发现未知字符:"%s",在标签:%s中,位置:%d。已替换为空格。',str(j),str,j);endendlabelSequences{i}=seq;end注意:空格在charSet中已经是最后一个,所以索引为numClasses(即length(charSet))。这样修改后,当遇到未知字符时,程序不会报错,而是将其映射为空格,并给出警告。另外,建议在训练前检查所有标签,确保没有未知字符,以避免训练数据错误。我们可以提前检查所有标签中的字符:%获取所有标签字符串中的所有字符allChars=unique([labelStrings{:}]);%注意:labelStrings是字符串数组,需要转换为字符数组%或者allChars=unique(char(join(labelStrings,'')));%将所有的字符串连接起来,然后取唯一字符%检查是否有不在charSet中的字符missingChars=setdiff(allChars,charSet);if~isempty(missingChars)warning('发现以下不在字符集中的字符:%s',strjoin(missingChars,','));end我们可以将这段检查代码放在转换序列之前。完整修改后的标签处理部分:%定义字符集charSet='0123456789+-×÷=';%字符集,包含空格numClasses=length(charSet);%字符类别数(包含空格)%...其他代码...%获取所有标签字符串中的所有字符allChars=unique(char(join(labelStrings,'')));missingChars=setdiff(allChars,charSet);if~isempty(missingChars)warning('发现以下不在字符集中的字符:%s',strjoin(missingChars,','));end%创建字符到索引的映射char2idx=containers.Map();fori=1:numClasseschar2idx(charSet(i))=i;end%转换标签为数字序列(包含未知字符处理)labelSequences=cell(numel(labels),1);fori=1:numel(labels)str=char(labels(i));seq=zeros(1,length(str));forj=1:length(str)ifisKey(char2idx,str(j))seq(j)=char2idx(str(j));elseseq(j)=numClasses;%映射到空格(最后一个字符)endendlabelSequences{i}=seq;end这样,程序就不会因为未知字符而报错。注意:在训练过程中,空格(索引为numClasses)会被当作一个有效的类别进行训练。因此,网络会学习到空格。但是,我们原本就希望空格作为分隔符或填充符,所以这样处理是合理的。最后,请确保在训练网络时,输出层的类别数设置为numClasses(即length(charSet))。在之前的网络构建中,我们使用:outputLayer=sequenceClassificationLayer('Name','output','Classes',1:numClasses);但是,注意:sequenceClassificationLayer用于序列分类,而我们的任务是序列到序列的映射(每个时间步输出一个字符类别)。因此,我们应该使用sequenceOutputLayer(结合CTCLoss)或者使用transformer等结构。不过,根据之前的代码,我们使用的是卷积网络+双向LSTM+CTC损失,所以输出层应该是一个全连接层+softmax,然后使用CTC损失。在之前的网络定义中,我们使用了:outputLayer=fullyConnectedLayer(numClasses,'Name','fc');softmaxLayer('Name','softmax');%然后需要自定义CTC损失层(或使用内置的CTCLoss)因此,确保全连接层的输出大小为numClasses。修改后的完整代码:由于代码较长,这里只给出修改后的标签处理部分。其他部分保持不变。请将标签处理部分替换为上述修改后的代码。这样,程序在遇到未知字符时就不会报错,而是将其替换为空格。</think>### 错误分析与解决方案 #### 错误原因: 错误发生在字符映射环节: ```matlab 错误使用 索引 此容器中不存在指定的键。 出错 tranorc (第 40行) seq(j) = char2idx(str(j)); ``` 这表明标签字符串中包含了字符集`charSet`中未定义的字符。当尝试使用`char2idx(str(j))`映射时,该字符不存在于`containers.Map`对象中。 ### 完整修正方案 ```matlab % === 字符集定义与未知字符处理 === charSet = '0123456789+-×÷= '; % 基础字符集 unknownChar = '
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值