C# 文本哈希技巧在Python和C中产生不同的结果#
我试图将经过培训的模型移动到生产环境中,但在尝试复制C#中Keras hashing_trick()函数的行为时遇到了一个问题。当我对句子进行编码时,我的输出在C#中与在python中不同: Text:“信息-配置处理已完成。” Python:[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,0,0,0,0,433,426,425,461,336,146,52] (从调试器复制,两个序列的长度均为30) 我所尝试的:C# 文本哈希技巧在Python和C中产生不同的结果#,c#,python,nlp,C#,Python,Nlp,我试图将经过培训的模型移动到生产环境中,但在尝试复制C#中Keras hashing_trick()函数的行为时遇到了一个问题。当我对句子进行编码时,我的输出在C#中与在python中不同: Text:“信息-配置处理已完成。” Python:[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,0,0,0,0,4
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();
}
}
public uint[]HashingTrick(字符串数据)
{
const int VOCAB_SIZE=534;//通过模型的python调试确定
var filters=“!\$%&()*+,-./:;?@[\]^{\\}~\t\n”.ToCharArray().ToList();
filters.ForEach(x=>
{
数据=数据。替换(x,'\0');
});
string[]parts=data.Split(“”);
var encoded=新列表();
parts.ToList().ForEach(x=>
{
使用(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);
编码。添加(val%(VOCAB_大小-1)+1);
}
});
返回PadSequence(编码,30);
}
专用单元[]焊盘顺序(列表序号,内部最大值)
{
如果(序号<最大值)
{
while(seq.CountmaxLen)
{
返回seq.GetRange(seq.Count-maxLen-1,maxLen.ToArray();
}
其他的
{
返回seq.ToArray();
}
}
可以找到散列技巧的keras实现
如果有帮助,我将使用ASP.NET Web API作为解决方案类型 您的代码最大的问题是,它无法解释Python的
int
是一个任意精度的整数,而C#的uint
只有32位。这意味着Python正在计算散列中所有128位的模,而C#不是(而且BitConverter.ToUInt32
在任何情况下都是错误的,因为endianness是错误的)。另一个让您感到困惑的问题是,\0
不会在C#中终止字符串,并且\0
不能只添加到MD5哈希中而不更改结果
以尽可能简单的方式翻译:
int[] hashingTrick(string text, int n, string filters, bool lower, string split) {
var splitWords = String.Join("", text.Where(c => !filters.Contains(c)))
.Split(new[] { split }, StringSplitOptions.RemoveEmptyEntries);
return (
from word in splitWords
let bytes = Encoding.UTF8.GetBytes(lower ? word.ToLower() : word)
let hash = MD5.Create().ComputeHash(bytes)
// add a 0 byte to force a non-negative result, per the BigInteger docs
let w = new BigInteger(hash.Reverse().Concat(new byte[] { 0 }).ToArray())
select (int) (w % (n - 1) + 1)
).ToArray();
}
样本使用:
const int vocabSize = 534;
Console.WriteLine(String.Join(" ",
hashingTrick(
text: "Information - The configuration processing is completed.",
n: vocabSize,
filters: "!#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n",
lower: true,
split: " "
).Select(i => i.ToString())
));
这段代码有各种各样的低效之处:与使用
StringBuilder
相比,使用LINQ过滤字符效率非常低,我们在这里并不真正需要BigInteger
,因为MD5总是正好是128位,但是优化(如果需要)是留给读者的一项练习,就像填充结果一样(您已经有了一个函数)。我没有解决试图与C#抗争以获得正确的哈希值的问题,而是采取了不同的方法来解决这个问题我决定使用@Jeron Mostert的哈希函数实现对数据集进行预哈希,然后再将其输入模型
这个解决方案更易于实现,最终的效果与原始文本哈希一样好。给像我这样尝试进行跨语言哈希的人的建议是:不要这样做,这是一个非常头痛的问题!使用一种语言对文本数据进行哈希,并找到一种方法来创建包含所有所需信息的有效数据集感谢您提供的示例!似乎此代码适用于较小的句子(如问题中的句子),但适用于更详细的大型句子(假设这些句子可以超过100个单词)输出不正确。这是因为我有一个更大的字符串,因此需要散列更多的位吗?我不知道幻数
534
从哪里来——这是我调查的第一行。第二是看看哪些数字是正确的——在上面的代码中,每个整数对应一个散列字,所以如果存在差异,这是因为字符串的分割方式不同,或者结果的收集方式不同。我没有仔细调试Python代码(例如,尝试“配置”--Python是生成三个数字还是只生成一个数字?)另一方面,根据应用程序的不同,您可能希望了解直接运行Python代码的方法,而不是先将代码转换为C(您可以在同一应用程序中使用C提供API端点,并调用Python代码)。重新设计控制盘从来都不是一个好主意,尤其是如果当前控制盘功能完善的话。神奇的数字534来自于我正在使用的数据集中不同的总字数。这个数字用于创建哈希以及在Keras模型的嵌入层中。我试着使用IronPython,但没有使用hashlib库IronPython不支持Keras使用的y,这是因为hashlib是IronP不支持的C扩展
217 142 262 113 319 413