我试图将一个经过训练的模型移到生产环境中,在尝试复制C#中Keras hashing_trick()函数的行为时遇到了一个问题。当我对句子进行编码时,我在C语言中的输出与在python中的输出不同:
文本:“信息-配置处理完成。”
Python:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 217 142 262 113 319 413]
C#:【0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,433,426,425,461,336,146,52]
(从调试器复制,两个序列的长度都为30)
我所做的:
我的代码(下面)是我的Keras hashing_-trick函数的实现。给出一个输入语句,然后函数将返回相应的编码序列。在
public uint[] HashingTrick(string data)
{
const int VOCAB_SIZE = 534; //Determined through python debugging of model
var filters = "!#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n".ToCharArray().ToList();
filters.ForEach(x =>
{
data = data.Replace(x, '\0');
});
string[] parts = data.Split(' ');
var encoded = new List<uint>();
parts.ToList().ForEach(x =>
{
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.UTF8.GetBytes(x);
byte[] hashBytes = md5.ComputeHash(inputBytes);
uint val = BitConverter.ToUInt32(hashBytes, 0);
encoded.Add(val % (VOCAB_SIZE - 1) + 1);
}
});
return PadSequence(encoded, 30);
}
private uint[] PadSequence(List<uint> seq, int maxLen)
{
if (seq.Count < maxLen)
{
while (seq.Count < maxLen)
{
seq.Insert(0, 0);
}
return seq.ToArray();
}
else if (seq.Count > maxLen)
{
return seq.GetRange(seq.Count - maxLen - 1, maxLen).ToArray();
}
else
{
return seq.ToArray();
}
}
散列技巧的keras实现可以找到here
如果有帮助的话,我正在使用ASP.NETwebapi作为我的解决方案类型。在
我没有解决试图与C斗争以获得哈希的问题,而是采用了不同的方法来解决这个问题。当我制作数据集来训练模型(这毕竟是一个机器学习项目)时,我决定使用@Jeron Mostert的哈希函数实现在将数据集输入模型之前对其进行预哈希。在
这个解决方案更容易实现,最终的工作效果和原始文本哈希一样好。对于那些像我这样尝试跨语言哈希的人来说,一句忠告:不要这样做,这会让人头疼!使用一种语言来散列文本数据,并找到一种方法来创建一个包含所有所需信息的有效数据集。在
代码最大的问题是它没有考虑到Python的}不能在不改变结果的情况下直接添加到MD5哈希中。在
int
是任意精度的整数,而C的uint
只有32位。这意味着Python正在计算hash中所有128位的模,而C没有(而且BitConverter.ToUInt32
在任何情况下都是错误的,因为endianness是错误的)。另一个问题是\0
不能终止C中的字符串,而且{以尽可能直接的方式翻译:
样品使用:
^{pr2}$这段代码有各种各样的低效:与使用
StringBuilder
相比,使用LINQ过滤字符的效率非常低,而且我们在这里并不需要BigInteger
,因为MD5总是精确的128位,但是优化(如果必要)留给读者作为练习,就像填充结果一样(您已经有了一个函数)。在相关问题 更多 >
编程相关推荐