TimeDistributed
Denseレイヤーの結果を処理するカスタムレイヤーを作成しました。
処理された結果をメトリックに使用し、後で損失関数の一部として使用したいので、NNの結果を後処理するのではなく、レイヤーを使用することを選択しました(現在、処理された結果を使用しないため、損失を出します。0.0
カスタムレイヤーの出力に対するの重み。
2つの出力の存在に対応するために、train_generator
とval_generator
を変更して、ラベルを2回(リスト内で)生成しました。
ただし、次のエラーが発生します。
File "/home/user/experiments/LSTM/2/S1B.py", line 324, in <module>
main()
File "/home/user/experiments/LSTM/2/S1B.py", line 118, in main
history=model.fit_generator(train_generator(train_list), steps_per_epoch=len(train_list), epochs=30, verbose=1,validation_data=val_generator(val_list),validation_steps=len(val_list),callbacks=callbacks_list)
File "/home/user/.local/lib/python3.6/site-packages/keras/legacy/interfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "/home/user/.local/lib/python3.6/site-packages/keras/engine/training.py", line 1418, in fit_generator
initial_epoch=initial_epoch)
File "/home/user/.local/lib/python3.6/site-packages/keras/engine/training_generator.py", line 217, in fit_generator
class_weight=class_weight)
File "/home/user/.local/lib/python3.6/site-packages/keras/engine/training.py", line 1211, in train_on_batch
class_weight=class_weight)
File "/home/user/.local/lib/python3.6/site-packages/keras/engine/training.py", line 789, in _standardize_user_data
exception_prefix='target')
File "/home/user/.local/lib/python3.6/site-packages/keras/engine/training_utils.py", line 102, in standardize_input_data
str(len(data)) + ' arrays: ' + str(data)[:200] + '...')
ValueError: Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 2 array(s), but instead got the following list of 1 arrays: [array([[[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, 0, ..., 0, 0, 0],
[0, 0, 0, ......
私のコードは:
import numpy as np
import glob
from os.path import isfile, join
import time
import random
dev_out= open ('dev_out.txt','w')
### CPU option (set to 1 to run on CPU):
if (0):
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
###
import keras
from keras.models import Model
from keras.layers import Input, LSTM, Dense, TimeDistributed,Lambda, Dropout, Activation, Layer
from keras.metrics import top_k_categorical_accuracy
from keras.callbacks import ModelCheckpoint
import keras.backend as K
###
import matplotlib
matplotlib.use('Agg') # prevents it from failing when there is no display
import matplotlib.pyplot as plt
###
name='S1'
model_designation=str(name)+'_'
data_dir='data'
train_val_split=0.2 # portion to be placed in validation
train_control_number=0
val_control_number=0
batch_size = 16
def basic_LSTM(features_num):
net_input = Input(shape=(None, features_num))
L=(LSTM(40, return_sequences=True))(net_input)
#model.add(LSTM(40, return_sequences=True))
#model.add(LSTM(40, return_sequences=True))
SoftDense= TimeDistributed(Dense(features_num, activation='softmax'), name='SoftDense')(L)
Scoring = ScoringLayer(name='Scoring')(SoftDense)
#Scoring=Dense(features_num, activation='softmax',name='Scoring')(SoftDense) #FAKE
model = Model(inputs=[net_input], outputs=[SoftDense,Scoring])
print(model.summary())
model.compile(loss={'SoftDense' :'categorical_crossentropy','Scoring': 'categorical_crossentropy' },
loss_weights={'SoftDense': 1., 'Scoring': 0.0},
optimizer='adam',
metrics={'SoftDense': ['accuracy',my_3D_top_5,my_3D_top_10]})
return (model)
class ScoringLayer(Layer):
def __init__(self, **kwargs):
super(ScoringLayer, self).__init__(**kwargs)
def build(self, input_shape):
super(ScoringLayer, self).build(input_shape)
def call(self, x):
max_val=K.max(x,axis=2,keepdims=True) #[0 - seq num; 1 - step in seq; 2 - onehot result]
#answer=K.dot (x,max_val)
answer=K.batch_dot (max_val,x)
#for debug:
dev_out.write('\nx\n')
dev_out.write(str(x))
dev_out.write('\nmax_val\n')
dev_out.write(str(max_val))
dev_out.write('\nanswer\n')
dev_out.write(str(answer))
dev_out.write('\n***\n')
####
return (answer)
def compute_output_shape(self, input_shape):
return (input_shape)
def main ():
input_files=glob.glob(join(data_dir,'*npy'))
data_list,dim=loader(input_files)
data_list=discard_duplicates(data_list)
train_list,val_list=data_spliter(data_list)
train_list=group_data(train_list,batch_size)
val_list=group_data(val_list,batch_size)
filepath = "saved-model-"+model_designation+"-{epoch:02d}.hdf5"
checkpoint = ModelCheckpoint(filepath, save_best_only=False)
callbacks_list=[checkpoint]
model=basic_LSTM(dim)
history=model.fit_generator(train_generator(train_list), steps_per_epoch=len(train_list), epochs=30, verbose=1,validation_data=val_generator(val_list),validation_steps=len(val_list),callbacks=callbacks_list)
report(history)
def discard_duplicates(data_list):
output=[]
list_of_sizes=[]
for data in data_list:
list_of_sizes.append(list(data.shape)[1])
data_list = [x for _, x in sorted(zip(list_of_sizes,data_list), key=lambda pair: pair[0])]
output.append(data_list[0])
for i in range (len(data_list)-1):
if (np.array_equal(data_list[i],data_list[i+1])):
pass
else:
output.append(data_list[i+1])
print (len(data_list))
print (len(output))
random.shuffle(output)
return (output)
def group_data(data_list,size): # groups data and elongate it to match
output=[]
list_of_sizes=[]
for data in data_list:
list_of_sizes.append(list(data.shape)[1])
data_list = [x for _, x in sorted(zip(list_of_sizes,data_list), key=lambda pair: pair[0])]
while len(data_list)>size:
this=data_list[:size]
data_list=data_list[size:]
combined=(elongate_and_combine(this))
output.append(combined)
combined=(elongate_and_combine(data_list))
output.append(combined)
random.shuffle(output)
return (output)
def elongate_and_combine(data_list):
max_length= (list(data_list[-1].shape)[1])
last_element=list.pop(data_list)
output=last_element
stop_codon=last_element[0,(max_length-1),:]
stop_codon=stop_codon.reshape(1,1,stop_codon.size)
for data in data_list:
size_of_data=list(data.shape)[1]
while size_of_data<max_length:
data=np.append(data, stop_codon, axis=1)
size_of_data=list(data.shape)[1]
output=np.append(output, data, axis=0)
return (output)
def train_generator(data_list):
while True:
global train_control_number
train_control_number=cycle_throught(len(data_list),train_control_number)
#print (train_control_number)
this=data_list[train_control_number]
x_train = this [:,:-1,:] # all but the last 1
y_train = this [:,1:,:] # all but the first 1
yield (x_train, [y_train,y_train])
def val_generator(data_list):
while True:
global val_control_number
val_control_number=cycle_throught(len(data_list),val_control_number)
#print (val_control_number)
this=data_list[val_control_number]
x_train = this [:,:-1,:] # all but the last 1
y_train = this [:,1:,:] # all but the first 1
yield (x_train, [y_train,y_train]) # double labels for double outputs
def cycle_throught (total,current):
current+=1
if (current==total):
current=0
return (current)
def loader(input_files):
data_list=[]
for input_file in input_files:
a=np.load (input_file)
incoming_shape=list(a.shape)
requested_shape=[1]+incoming_shape
a=a.reshape(requested_shape)
#print (a.shape)
data_list.append(a)
return (data_list,incoming_shape[-1])
def data_spliter(input_list):
val_num=int(len(input_list)*train_val_split)
validation=input_list[:val_num]
train=input_list[val_num:]
return (train,validation)
def my_3D_top_5(true, pred):
features_num=int(list(pred.shape)[-1])
true = K.reshape(true, (-1, features_num))
pred = K.reshape(pred, (-1, features_num))
return top_k_categorical_accuracy(true, pred, k=5)
def my_3D_top_10(true, pred):
features_num=int(list(pred.shape)[-1])
true = K.reshape(true, (-1, features_num))
pred = K.reshape(pred, (-1, features_num))
return top_k_categorical_accuracy(true, pred, k=10)
def report(history) :
print(history.history.keys())
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
acc_5=history.history['my_3D_top_5']
val_acc_5=history.history['val_my_3D_top_5']
acc_10=history.history['my_3D_top_10']
val_acc_10=history.history['val_my_3D_top_10']
epochs = range(1, len(acc) + 1)
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 6))
axes[0][0].plot(epochs, acc, 'bo', label='Training acc')
axes[0][0].plot(epochs, val_acc, 'b', label='Validation acc')
axes[0][0].set_title('Training and validation accuracy')
axes[0][0].legend()
axes[0][1].plot(epochs, loss, 'ro', label='Training loss')
axes[0][1].plot(epochs, val_loss, 'r', label='Validation loss')
axes[0][1].set_title('Training and validation loss')
axes[0][1].legend()
axes[1][0].plot(epochs, acc_5, 'go', label='Training acc over top 5')
axes[1][0].plot(epochs, val_acc_5, 'g', label='Validation acc over top 5')
axes[1][0].set_title('Training and validation accuracy over top 5')
axes[1][0].legend()
axes[1][1].plot(epochs, acc_10, 'mo', label='Training acc over top 10')
axes[1][1].plot(epochs, val_acc_10, 'm', label='Validation acc over top 10')
axes[1][1].set_title('Training and validation accuracy over top 10')
axes[1][1].legend()
fig.tight_layout()
fig.savefig('fig_'+name+'.png') # save the figure to file
start=time.time()
main()
finish=time.time()
print (str(int(start-finish))+' Seconds.')
のプリントアウトを確認するScoringLayer
と、その中のテンソルのサイズが予想どおりであることがわかります。
x
Tensor("SoftDense/Reshape_1:0", shape=(?, ?, 501), dtype=float32)
max_val
Tensor("Scoring/Max:0", shape=(?, ?, 1), dtype=float32)
answer
Tensor("Scoring/MatMul:0", shape=(?, ?, 501), dtype=float32)
したがって、これが問題の原因ではないようです。
私の間違いは、行列の乗算に適切なツールを使用していなかったことです。具体的には、でScoringLayer
、私は使用する必要がありました
answer=max_val*x
使用する代わりに
answer=K.batch_dot (max_val,x)
これで問題は解決します。
使用された新しいアーキテクチャはで使用されている名前を変更するhistory
ので、私も変更する必要がreport
ありました。
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
acc_5=history.history['my_3D_top_5']
val_acc_5=history.history['val_my_3D_top_5']
acc_10=history.history['my_3D_top_10']
val_acc_10=history.history['val_my_3D_top_10']
と
acc = history.history['SoftDense_acc']
val_acc = history.history['val_SoftDense_acc']
loss = history.history['SoftDense_loss']
val_loss = history.history['val_SoftDense_loss']
acc_5=history.history['SoftDense_my_3D_top_5']
val_acc_5=history.history['val_SoftDense_my_3D_top_5']
acc_10=history.history['SoftDense_my_3D_top_10']
val_acc_10=history.history['val_SoftDense_my_3D_top_10']
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加