Python 从Tensorflow转换->;CoreML 3.0用于插槽/意图检测
我试图在我的Swift应用程序中使用这个代码库()创建的一些模型 我能够将Python 从Tensorflow转换->;CoreML 3.0用于插槽/意图检测,python,swift,tensorflow,chatbot,coreml,Python,Swift,Tensorflow,Chatbot,Coreml,我试图在我的Swift应用程序中使用这个代码库()创建的一些模型 我能够将lstm\u nopooling、lstm\u nopooling 300和lstm转换为CoreML 在model.py中,我使用了以下代码: def save_model(self): joblib.dump(self.summary, 'models/' + self.name + '.txt') self.model.save('models/' + self.name + '.h5') t
lstm\u nopooling
、lstm\u nopooling 300
和lstm
转换为CoreML
在model.py
中,我使用了以下代码:
def save_model(self):
joblib.dump(self.summary, 'models/' + self.name + '.txt')
self.model.save('models/' + self.name + '.h5')
try:
coreml_model = coremltools.converters.keras.convert(self.model, input_names="main_input", output_names=["intent_output","slot_output"])
coreml_model.save('models/' + self.name + '.mlmodel')
except:
pass
print("Saved model to disk")
我试图将向量转换回意图和槽
我有这个,但是
func tokenizeSentences(instr: String) -> [Int] {
let s = instr.lowercased().split(separator: " ")
var ret = [Int]()
if let filepath = Bundle.main.path(forResource: "atis.dict.vocab", ofType: "csv") {
do {
let contents = try String(contentsOfFile: filepath)
print(contents)
var lines = contents.split { $0.isNewline }
var pos = 0
for word in s {
if let index = lines.firstIndex(of: word) {
print(index.description + " " + word)
ret.append(index)
}
}
return ret
} catch {
// contents could not be loaded
}
} else {
// example.txt not found!
}
return ret
}
func predictText(instr:String) {
let model = lstm_nopooling300()
guard let mlMultiArray = try? MLMultiArray(shape:[20,1,1],
dataType:MLMultiArrayDataType.int32) else {
fatalError("Unexpected runtime error. MLMultiArray")
}
let tokens = tokenizeSentences(instr: instr)
for (index, element) in tokens.enumerated() {
mlMultiArray[index] = NSNumber(integerLiteral: element)
}
guard let m = try? model.prediction(input: lstm_nopooling300Input.init(main_input: mlMultiArray))
else {
fatalError("Unexpected runtime error. MLMultiArray")
}
let mm = m.intent_output
let length = mm.count
let doublePtr = mm.dataPointer.bindMemory(to: Double.self, capacity: length)
let doubleBuffer = UnsafeBufferPointer(start: doublePtr, count: length)
let output = Array(doubleBuffer)
print("******** intents \(mm.count) ********")
print(output)
let mn = m.slot_output
let length2 = mn.count
let doublePtr2 = mm.dataPointer.bindMemory(to: Double.self, capacity: length2)
let doubleBuffer2 = UnsafeBufferPointer(start: doublePtr2, count: length2)
let output2 = Array(doubleBuffer2)
print("******** slots \(mn.count) ********")
print(output2)
}
}
当我运行代码时,出于以下目的,我得到了这个被截断的代码:
********意图540*******
[0.0028914143331348896、0.0057610333897173405、4.1651015635579824e-05、,
0.15935245156288147、5.6665314332349226e-05、5.7797817134996876e-05、0.004430230706901605、0.00012486864579841495、0.0004683282459154725、0.003053907072171569、3.806956738117151e-05、0.012112349271774292、5.861848694621585e-05、0.003134472525428、
我认为,问题在于ID位于pickle文件中,因此可能在atis/atis.train.pkl中
我所做的只是训练模型并将它们转换成CoreML,现在我正在尝试使用它,但不确定下一步该怎么做
我有一个文本字段,输入“伦敦当前天气”,我希望得到类似的内容(这来自运行example.py)
{'intent':'weather_intent','slots':[{'name':'city','value':'London'}]}
下面是coreml输入/输出
多亏了@MatthijsHollemans,我才知道该怎么办 在data_processing.py中,我添加了以下内容:
with open('atis/wordlist.csv', 'w') as f:
for key in ids2words.keys():
f.write("%s\n"%(ids2words.keys[key]))
with open('atis/wordlist_slots.csv', 'w') as f:
for key in ids2slots.keys():
f.write("%s\n"%(ids2slots[key]))
with open('atis/wordlist_intents.csv', 'w') as f:
for key in ids2intents.keys():
f.write("%s\n"%(ids2intents[key]))
这允许我使用wordlist.csv正确标记
然后当我得到响应时,使用mm.count
是错误的,它应该是output.count
例如,我可以看到意图
查找具有最大值的元素,然后在wordlist_intents.csv(我将其转换为数组,可能应该是字典)中查找可能的意图
我仍然需要做插槽,但基本想法是一样的
关键是将python中使用的字典输出到csv文件,然后将其导入到项目中
更新
我意识到当mm.count为540时,这是因为它可以在句子中包含20个单词,因此它可以返回那么多。所以在我的例子中,我需要将单词按空格分割,然后循环多次,因为我不会得到比单词更多的插槽
我在SwiftUI中这样做,所以我还必须创建一个可观察对象,以便使用EnvironmentObject传递术语
因此,为了正确地循环内存中的双数组,我包含了实现我期望的最新代码
func predictText(instr:String) {
let model = lstm_nopooling300()
guard let mlMultiArray = try? MLMultiArray(shape:[20,1,1],
dataType:MLMultiArrayDataType.int32) else {
fatalError("Unexpected runtime error. MLMultiArray")
}
let tokens = tokenizeSentences(instr: instr)
let sent = instr.split(separator: " ")
print(instr)
print(tokens)
for (index, element) in tokens.enumerated() {
mlMultiArray[index] = NSNumber(integerLiteral: element)
}
guard let m = try? model.prediction(input: lstm_nopooling300Input.init(main_input: mlMultiArray))
else {
fatalError("Unexpected runtime error. MLMultiArray")
}
let mm = m.intent_output
let length = mm.count
let doublePtr = mm.dataPointer.bindMemory(to: Double.self, capacity: length)
var intents = [String]()
for i in 0...sent.count - 1 {
let doubleBuffer = UnsafeBufferPointer(start: doublePtr + i * 27, count: 27)
let output = Array(doubleBuffer)
let intent = convertVectorToIntent(vector: output)
intents.append(intent)
}
print(intents)
let mn = m.slot_output
let length2 = mn.count
let doublePtr2 = mn.dataPointer.bindMemory(to: Double.self, capacity: length2)
var slots = [String]()
for i in 0...sent.count - 1 {
let doubleBuffer2 = UnsafeBufferPointer(start: doublePtr2 + i * 133, count: 133)
let output2 = Array(doubleBuffer2)
var slot = ""
slot = convertVectorToSlot(vector: output2)
slots.append(slot)
slots.append(sent[i].description)
}
print(slots)
}
您运行了哪种代码来生成该输出?@smac89-我编写了一个应用程序,我正在尝试使用它,这就是我运行的代码。如果您查看swift代码,“打印(输出)”'是我显示的,但我只想显示返回值的一小部分。我添加了更多代码,因为我忘记了一个函数,并且显示了所有函数可能会有所帮助。模型实际输出什么?原始model.py显示需要argmax来获取索引,然后在表中查找。从您的问题来看,不清楚输出数据看起来像,以及应该如何获取这些argmax。@MatthijsHollemans-谢谢。添加了我键入的内容和我期望得到的内容,或者与之相近的内容。但我问你从模型中实际得到了什么。有多少个输出,它们的数据类型是什么,它们的形状是什么,等等?