Python 试图理解LSTM和不同长度的输入

Python 试图理解LSTM和不同长度的输入,python,numpy,keras,lstm,Python,Numpy,Keras,Lstm,我试图理解LSTM网络是如何工作的:我根据 但是检测单词的积极或消极用法。因此,对于bad.txt: yuck bad no bleh never hate awful 和good.txt: yum good yes hooray great love 现在,我可以得到一个相当“准确”的正/负检测器,至少对于这个小子集(我知道,过度拟合…)。当我输入“伟大”时,它表示积极,“可怕”时,它表示消极 然而,当我输入“reat”时,它表示99%为负,“wful”表示99%为正。据我所知,每一个“第

我试图理解LSTM网络是如何工作的:我根据 但是检测单词的积极或消极用法。因此,对于bad.txt:

yuck
bad
no
bleh
never
hate
awful
和good.txt:

yum
good
yes
hooray
great
love
现在,我可以得到一个相当“准确”的正/负检测器,至少对于这个小子集(我知道,过度拟合…)。当我输入“伟大”时,它表示积极,“可怕”时,它表示消极

然而,当我输入“reat”时,它表示99%为负,“wful”表示99%为正。据我所知,每一个“第二个字母”神经元都在寻找训练过的东西的第二个字母,这可能就是原因。还有,可能是因为空格用于填充任何较短的单词,有没有更合适的方法?也就是说,有没有更合适的方法来检测不同长度的事物,比如单词或音频片段?我知道LSTM可以用于顺序/流式数据,如来自文本流文件的字符,如果将其输入到这样的算法中,“可怕”将被伪造的“wful”抵消。。。有什么好方法可以纠正这个问题吗

# Load LSTM network and generate text
import sys
import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import LSTM
from keras.callbacks import ModelCheckpoint
from keras.utils import np_utils
import time

# create mapping of unique chars to integers, and a reverse mapping
chars = " abcdefghijklmnopqrstuvwxyz"
char_to_int = dict((c, i) for i, c in enumerate(chars))
int_to_char = dict((i, c) for i, c in enumerate(chars))
## summarize the loaded data
#n_chars = len(raw_text)
n_vocab = len(chars)
#print ("Total Characters: "+ str(n_chars))
#print ("Total Vocab: "+ str(n_vocab))
## prepare the dataset of input to output pairs encoded as integers
#seq_length = 100
dataX = []
dataY = []
seq_length = 7
for i in range(1000):
    with open('bad.txt') as bad:
        for line in bad:
            print(line+' mapping to [1,0]')
            nums = [char_to_int[n] for n in line.lower() if n in chars]
            while len(nums) < seq_length:
                nums.append(0)# " "
            dataX.append(nums)
            dataY.append([1,0])
    with open('good.txt') as bad:
        for line in bad:
            print(line+' mapping to [0,1]')
            nums = [char_to_int[n] for n in line.lower() if n in chars]
            while len(nums) < seq_length:
                nums.append(0)# " "
            dataX.append(nums)
            dataY.append([0,1])

n_patterns = len(dataX)
print ("Total Patterns: "+ str(n_patterns))

X = numpy.reshape(dataX, (n_patterns, seq_length, 1))
# normalize
X = X / float(n_vocab)
print(X[0:10])
# one hot encode the output variable
y = numpy.array(dataY)#np_utils.to_categorical(dataY)
# define the LSTM model
model = Sequential()
model.add(LSTM(20, input_shape=(X.shape[1], X.shape[2])))
#model.add(Dropout(0.01))
model.add(Dense(y.shape[1], activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam')
#This was step1.
filepath="simpleweights-improvement-{epoch:02d}-{loss:.4f}.hdf5"
checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min')
callbacks_list = [checkpoint]
model.fit(X, y, epochs=20, batch_size=128, callbacks=callbacks_list)

# pick a random seed
start = numpy.random.randint(0, len(dataX)-1)
pattern = dataX[start]
print ("Seed:")
print ("\"", ''.join([int_to_char[value] for value in pattern]), "\"")
# generate characters
while True:
    word = input('word: ')
    numberize = []
    for l in word:
        if l in char_to_int:
            numberize.append(char_to_int[l])
    while len(numberize) < seq_length:
        numberize.append(0) #this space, first
    print(numberize)
    numberize = numpy.reshape(numberize, (1, len(numberize), 1))
    numberize = numberize / float(n_vocab) #normalize!
    print(numberize)
    result = (model.predict(numberize,verbose=0))
    print(result)
    #Just one. could do many at a time.
    if result[0][1] > result[0][0]:
        print('positive')
    else:
        print('negative')
#加载LSTM网络并生成文本
导入系统
进口numpy
从keras.models导入顺序
从keras.layers导入稠密
从keras.layers导入退出
从keras.layers导入LSTM
从keras.callbacks导入模型检查点
从keras.utils导入np_utils
导入时间
#创建唯一字符到整数的映射和反向映射
chars=“abcdefghijklmnopqrstuvxyz”
char_to_int=dict((c,i)表示枚举(chars)中的i,c)
int_to_char=dict((i,c)表示枚举(chars)中的i,c)
##汇总加载的数据
#n_chars=len(原始文本)
n_vocab=len(字符)
#打印(“总字符数:+str(n_字符))
#打印(“总声音:+str(n_声音))
##准备以整数编码的输入到输出对的数据集
#序号长度=100
数据x=[]
数据Y=[]
序号长度=7
对于范围(1000)内的i:
将open('bad.txt')设置为bad:
对于处于不良状态的线路:
打印(第+行“映射到[1,0]”)
nums=[char_to_int[n]表示行中的n。如果n表示字符,则为lower()
而长度(nums)<以下长度:
nums.append(0)#“
dataX.append(nums)
dataY.append([1,0])
将open('good.txt')设置为bad:
对于处于不良状态的线路:
打印(第+行“映射到[0,1]”)
nums=[char_to_int[n]表示行中的n。如果n表示字符,则为lower()
而长度(nums)<以下长度:
nums.append(0)#“
dataX.append(nums)
dataY.append([0,1])
n_patterns=len(dataX)
打印(“总图案:+str(n_图案))
X=numpy.重塑(数据X,(n个图案,序列长度,1))
#正常化
X=X/浮点数(n_/b)
打印(X[0:10])
#一个热编码输出变量
y=numpy.array(dataY)#np_utils.to_category(dataY)
#定义LSTM模型
模型=顺序()
添加(LSTM(20,输入_-shape=(X.shape[1],X.shape[2]))
#模型。添加(辍学率(0.01))
model.add(稠密(y.shape[1],activation='softmax'))
compile(loss='classifical\u crossentropy',optimizer='adam')
#这是第一步。
filepath=“SimpleLights改进-{epoch:02d}-{loss:.4f}.hdf5”
checkpoint=ModelCheckpoint(文件路径,monitor='loss',verbose=1,save\u best\u only=True,mode='min')
回调\u列表=[检查点]
model.fit(X,y,epochs=20,batch\u size=128,callbacks=callbacks\u list)
#随机挑选一个种子
start=numpy.random.randint(0,len(dataX)-1)
模式=数据x[开始]
打印(“种子:”)
打印(“\”,“”。连接([int\u to\u char[value]表示模式中的值]),“\”)
#生成字符
尽管如此:
word=输入('word:'))
编号=[]
对于文字中的l:
如果l在字符到整数中:
numberize.append(char\u to\u int[l])
而len(编号)结果[0][0]:
打印('正')
其他:
打印('负片')

您可能应该进行数据扩充培训,从原始示例创建示例,但缺少一个或两个字符。这是有道理的,如果要检测打字错误,使用一些字符替换而不是在输入上重复这些字符也是有道理的。似乎“hbte”或“yfs”或任何字符位于单词前面的单词之间的差别很小,但意义不大。我想知道是否有一种设置,其中数字是分类的,而不是a在值上紧靠b?啊,你当然应该尝试使用
嵌入层。每个字符都应该是唯一和独立的。您仍然在输入中使用序列号,但嵌入层将为这些数字中的每一个选择一组权重。