Issue with custom metric auc callback for keras - python

I am trying to implement custom roccallback for keras. The call back function I wrote is below. I have to achieve a target of 0.90.
AUROC callback:
class rocback(Callback):
def __init__(self, validation_data):
super(rocback, self).__init__()
# self.training_data = training_data
self.validation_data = validation_data
def on_train_begin(self, logs={}) :
return
def on_epoch_end(self, epoch, logs={}):
probs = self.model.predict(self.validation_data[0])
probs = np.round(probs)
y_true = self.validation_data[1]
y_true = np.round(y_true)
score = roc_auc_score(y_true, probs, average='micro')
logs['auc'] = score
Hence next callback which I wrote was to achieve the target.
class scoreTarget(Callback):
def __init__(self, target):
super(scoreTarget, self).__init__()
self.target = target
def on_epoch_end(self, epoch, logs={}):
acc = logs['auc']
if acc >= self.target:
self.model.stop_training = True
The list of call back used is below:
roc_callback = rocback((X_test_pooled_output, y_test))
early_stopping = EarlyStopping(patience=5)
tensorboard = TensorBoard()
reduce_lr = ReduceLROnPlateau(patience=3)
target = scoreTarget(0.90)
callbacks = [
roc_callback,
early_stopping,
tensorboard,
reduce_lr,
target,
]
The classifier function which I wrote is below:
class ReviewClassifier(Model):
def __init__(self):
super(ReviewClassifier, self).__init__()
self.dense_1 = Dense(64, activation='relu')
self.dense_2 = Dense(32, activation='relu')
self.dense_3 = Dense(16, activation='relu')
self.classify = Dense(1, activation='sigmoid')
self.dropout_1 = Dropout(0.2)
self.dropout_2 = Dropout(0.2)
self.dropout_3 = Dropout(0.2)
def call(self, inputs):
x = self.dense_1(inputs)
x = self.dropout_1(x)
x = self.dense_2(x)
x = self.dropout_2(x)
x = self.dense_3(x)
x = self.dropout_3(x)
x = self.classify(x)
return x
review_classifier = ReviewClassifier()
review_classifier.build((None, 768))
review_classifier.summary()
The compile funtcion I wrote is this:
review_classifier.compile(loss='binary_crossentropy',
optimizer='adam',metrics=[rocback])
fit function:
!rm -rf ./logs/*
history = review_classifier.fit(X_train_pooled_output, y_train,
batch_size=32, epochs=100,
callbacks=callbacks,
validation_data=(X_test_pooled_output, y_test))
The error received is:
Epoch 1/100
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-54-fd7595a2c88c> in <module>()
1 get_ipython().system('rm -rf ./logs/*')
----> 2 history = review_classifier.fit(X_train_pooled_output, y_train, batch_size=32, epochs=100,callbacks=callbacks, validation_data=(X_test_pooled_output, y_test))
9 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py in wrapper(*args, **kwargs)
975 except Exception as e: # pylint:disable=broad-except
976 if hasattr(e, "ag_error_metadata"):
--> 977 raise e.ag_error_metadata.to_exception(e)
978 else:
979 raise
TypeError: in user code:
/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py:805 train_function *
return step_function(self, iterator)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py:795 step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
/usr/local/lib/python3.7/dist-packages/tensorflow/python/distribute/distribute_lib.py:1259 run
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/distribute/distribute_lib.py:2730 call_for_each_replica
return self._call_for_each_replica(fn, args, kwargs)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/distribute/distribute_lib.py:3417 _call_for_each_replica
return fn(*args, **kwargs)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py:788 run_step **
outputs = model.train_step(data)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py:758 train_step
self.compiled_metrics.update_state(y, y_pred, sample_weight)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/compile_utils.py:408 update_state
metric_obj.update_state(y_t, y_p, sample_weight=mask)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/utils/metrics_utils.py:90 decorated
update_op = update_state_fn(*args, **kwargs)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/metrics.py:177 update_state_fn
return ag_update_state(*args, **kwargs)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/metrics.py:618 update_state **
matches = ag_fn(y_true, y_pred, **self._fn_kwargs)
TypeError: __init__() takes 2 positional arguments but 3 were given
Any idea what am I doing wrong in the custom callback which I created for roc?
Let me know what more inputs you need.

As we've mentioned in the comment, you can use built-in tf.keras.metrics.AUC while compiling the model, easy-fast-efficient. But also no problem to use either sklearn.metrics.roc_auc_score. But using it in callback may slow down your training time. Try this:
class ROAUCMetrics(tf.keras.callbacks.Callback):
def __init__(self, val_data):
super().__init__()
self.valid_x = val_data[0]
self.valid_y = val_data[1]
def on_train_begin(self, logs={}):
self.val_aucs = []
def on_epoch_end(self, epoch, logs={}):
pred = self.model.predict(self.valid_x)
val_auc = roc_auc_score(self.valid_y, pred, average='micro')
print('\nval-roc-auc: %s' % (str(round(val_auc,4))),end=100*' '+'\n')
self.val_aucs.append(val_auc)
return
# sklearn auc
roc = ROAUCMetrics(val_data=(x_val, y_val))
# tf.keras auc
model.compile(.., ..., metrics=["AUC"])
# running
model.fit(x_train, y_train, batch_size=1024,
epochs=..., callbacks=[roc],
validation_data=(x_val, y_val))
# get the values of auc, computed using sklearn auc
roc.val_aucs
However, note that both compute AUC differently, one uses Approximate AUC, another one uses Riemann sum, I've tested in one example and they pretty comparable but sometimes didn't.
Based on your 1st comment, your set up should look like this:
# (1)
# compile with no metrics - as we have custom callback metric to use
review_classifier.compile(loss='binary_crossentropy',optimizer='adam')
# (2)
# or,
# we can add another metrics e.g 'accuracy' or whatever
# here we use built-in AUC
review_classifier.compile(loss='binary_crossentropy',
optimizer='adam',metrics=['AUC'])
# sklearn auc
roc = ROAUCMetrics(val_data=(x_val, y_val))
early_stopping = EarlyStopping(patience=5)
tensorboard = TensorBoard()
reduce_lr = ReduceLROnPlateau(patience=3)
target = scoreTarget(0.90)
callbacks = [
roc,
early_stopping,
tensorboard,
reduce_lr,
target,
]
# fitting
model.fit(x_train, y_train, batch_size=1024,
epochs=..., callbacks=callbacks,
validation_data=(x_val, y_val))

Related

AttributeError: Can't get attribute 'GaitDataset' on <module '__main__' (built-in)>

I'm using PyTorch Lightning and PyTorch for LSTM classification. Whenever I train the model, this error shows:
File "<string>", line 1, in <module>
File "C:\Users\hisha\anaconda3\envs\FYP\lib\multiprocessing\spawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "C:\Users\hisha\anaconda3\envs\FYP\lib\multiprocessing\spawn.py", line 126, in _main
self = reduction.pickle.load(from_parent)
AttributeError: Can't get attribute 'GaitDataset' on <module '__main__' (built-in)>
I'm implementing time series classification using sequences. The original model and data module code is below:
class GaitDataset(Dataset):
def __init__(self, sequences):
self.sequences = sequences
def __len__(self):
return len(self.sequences)
def __getitem__(self, idx):
sequence, label = self.sequences[idx]
return dict(
sequence=torch.Tensor(sequence.to_numpy()),
label=torch.tensor(label).long()
)
class GaitDataModule(pl.LightningDataModule):
def __init__(self, train_sequences, test_sequences, batch_size):
super().__init__()
self.train_sequences = train_sequences
self.test_sequences = test_sequences
self.batch_size = batch_size
def setup(self, stage=None):
self.train_dataset = GaitDataset(self.train_sequences)
self.test_dataset = GaitDataset(self.test_sequences)
def train_dataloader(self):
return DataLoader(
self.train_dataset,
batch_size=self.batch_size,
shuffle=True,
num_workers=cpu_count()
)
def val_dataloader(self):
return DataLoader(
self.test_dataset,
batch_size=self.batch_size,
shuffle=False,
num_workers=cpu_count()
)
def test_dataloader(self):
return DataLoader(
self.test_dataset,
batch_size=self.batch_size,
shuffle=False,
num_workers=2
)
N_EPOCHS = 250
BATCH_SIZE = 64
data_module = GaitDataModule(train_sequences, test_sequences, BATCH_SIZE)
class SequenceModel(nn.Module):
def __init__(self, n_features, n_classes, n_hidden=256, n_layers=3):
super().__init__()
self.lstm = nn.LSTM(
input_size=n_features,
hidden_size=n_hidden,
num_layers=n_layers,
batch_first=True,
dropout=0.5
)
self.classifier = nn.Linear(n_hidden, n_classes)
def forward(self, x):
self.lstm.flatten_parameters()
_, (hidden, _) = self.lstm(x)
out = hidden[-1]
return self.classifier(out)
class GaitPredictor(pl.LightningModule):
def __init__(self, n_features: int, n_classes: int):
super().__init__()
self.model = SequenceModel(n_features, n_classes)
self.criterion = nn.CrossEntropyLoss()
def forward(self, x, labels=None):
output = self.model(x)
loss = 0
if labels is not None:
loss = self.criterion(output, labels)
return loss, output
def training_step(self, batch, batch_idx):
sequences = batch['sequence']
labels = batch['label']
loss, outputs = self(sequences, labels)
predictions = torch.argmax(outputs, dim=1)
step_accuracy = accuracy(predictions, labels)
self.log('train_loss', loss, prog_bar=True, logger=True)
self.log('train_accuracy', step_accuracy, prog_bar=True, logger=True)
return {'loss': loss, 'accuracy': step_accuracy}
def validation_step(self, batch, batch_idx):
sequences = batch['sequence']
labels = batch['label']
loss, outputs = self(sequences, labels)
predictions = torch.argmax(outputs, dim=1)
step_accuracy = accuracy(predictions, labels)
self.log('val_loss', loss, prog_bar=True, logger=True)
self.log('val_accuracy', step_accuracy, prog_bar=True, logger=True)
return {'loss': loss, 'accuracy': step_accuracy}
def test_step(self, batch, batch_idx):
sequences = batch['sequence']
labels = batch['label']
loss, outputs = self(sequences, labels)
predictions = torch.argmax(outputs, dim=1)
step_accuracy = accuracy(predictions, labels)
self.log('test_loss', loss, prog_bar=True, logger=True)
self.log('test_accuracy', step_accuracy, prog_bar=True, logger=True)
return {'loss': loss, 'accuracy': step_accuracy}
def configure_optimizers(self):
return optim.Adam(self.parameters(), lr=0.0001)
model = GaitPredictor(
n_features=len(FeatureColumns),
n_classes=len(label_encoder.classes_)
)
checkpoint_callback = ModelCheckpoint(
dirpath='checkpoints',
filename='best-checkpoint',
save_top_k=1,
verbose=True,
monitor='val_loss',
mode='min'
)
logger = TensorBoardLogger('lightning_logs', name='Gait')
trainer = pl.Trainer(
checkpoint_callback=checkpoint_callback,
logger=logger,
max_epochs=N_EPOCHS,
gpus=1,
progress_bar_refresh_rate=30
)
trainer.fit(model, data_module)
How to fix this error? I am using GaitDataset class which describes gait sequences for training, but it seems that Python is unable to import the class properly.
I followed this tutorial from YouTube:
https://youtu.be/PCgrgHgy26c
Environment:
python 3.9.7
pytorch 1.11.0
pytorch-lightning 1.5.10
Conda environment configured in Pycharm
This is due to lightning trying to load the data from the file. It cannot determine the 'GaitDataset'. I guess this is actually a bug in lightning since it should use the fully qualified name to resolve it.
Funny enough you can import it in your main file and it will be found.
Add
from your.package.here import GaitDataset
It gets funny if you have other wrapper logic happening.
Edit: See https://stackoverflow.com/a/68279928/1615430 for the cause of this error

How to print infomation in the get_gradient function?

I want to change the get_gradients method of Adam to execute gradient Centralization, the following code is from https://keras.io/examples/vision/gradient_centralization/
My question is why the code print('ttt') in method get_gradients prints nothing when fit function is executing?
print('dddd') works and print dddd in screen.
from tensorflow.keras.optimizers import Adam
import tensorflow as tf
class GCAdam(Adam):
def __init__(self, learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-7, amsgrad=False, name='Adam', **kwargs):
super().__init__(learning_rate=learning_rate, beta_1=beta_1, beta_2=beta_2, epsilon=epsilon, amsgrad=amsgrad, name=name, **kwargs)
print('dddd')
def get_gradients(self, loss, params):
# We here just provide a modified get_gradients() function since we are
# trying to just compute the centralized gradients.
grads = []
gradients = super().get_gradients()
print('ttt')
for grad in gradients:
grad_len = len(grad.shape)
if grad_len > 1:
axis = list(range(grad_len - 1))
grad -= tf.reduce_mean(grad, axis=axis, keep_dims=True)
grads.append(grad)
return grads
optimizergc = GCAdam(learning_rate=1e-4)
model.compile(loss="categorical_crossentropy", optimizer=optimizergc, metrics=["accuracy"])
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1,verbose=1)

Custom ImageDataGenerator (Keras) for large Dataset and multi input

I have been trying to implement a custom ImageDataGenerator for a two input and one output image classification model from an hdf5 file (large dataset of 88k paired images). The network works as follow:
Each pair of images is fed into a VGG16 model, for feature extraction purposes, (both network have shared parameters and the layers are frozen for training purposes)
The output of each VGG16 net is concatenated and fed into a 3-FC layers.
The final output is a probability to decide if these two images are compatible (top and bottom cloth types for outfit matching).
This is the code of my custom generator which reads an hdf5 with two dataset on it, the paired images (88000,2,224,224,3) and the labels (88000,), 1-match 0-notmatch.
class HDF5DataGenerator:
def __init__(self, dbPath, batchSize, preprocessors=None,aug=None,binarize=True,classes=2):
self.batchSize = batchSize
self.preprocessors = preprocessors
self.aug = aug
self.binarize = binarize
self.classes = classes
self.db = h5py.File(dbPath, 'r')
self.numImages = self.db['images'].shape[0]
def generator(self, passes=np.inf):
epochs=0
while epochs < passes:
idx = np.array(range(0,numImages),dtype='int')
np.random.shuffle(idx)
for i in np.arange(0, self.numImages, self.batchSize):
idxBatch = np.array(idx[i:i+batchSize])
idxBatch.sort()
imagesA = self.db['images'][idxBatch,0]
imagesB = self.db['images'][idxBatch,1]
labels = self.db['labels'][idxBatch]
if self.binarize:
labels = to_categorical(labels, self.classes)
if self.preprocessors is not None:
procImagesA = []
for image in imagesA:
for p in self.preprocessors:
image = p.preprocess(image)
procImagesA.append(image)
imagesA = np.array(procImagesA)
procImagesB = []
for image in imagesB:
for p in self.preprocessors:
image = p.preprocess(image)
procImagesB.append(image)
imagesB = np.array(procImagesB)
if self.aug is not None:
(imagesA,labels) = next(self.aug.flow(imagesA, labels, batch_size=self.batchSize))
(imagesB,labels) = next(self.aug.flow(imagesB, labels, batch_size=self.batchSize))
yield [imagesA,imagesB],labels
epochs +=1
def close(self):
self.db.close()
When passing the generator to the fit_generation function as the following:
trainGen = HDF5DataGenerator('train.hdf5',
BATCH_SIZE,
preprocessors=[mp,iap],
aug=aug,
classes=2)
history = model.fit(trainGen.generator(),
steps_per_epoch = trainGen.numImages // BATCH_SIZE,
#validation_data= testGen.generator(),
#validation_steps = testGen.numImages // BATCH_SIZE,
epochs=EPOCHS,
max_queue_size=10)
I get the following error which frankly I don't understand. I already checked the dimensionality of all the images written in the file since the incompatibility erro shows (None,224,224,1), which make me think that there was something wrong with the data, but that was not the issue.
ValueError: in user code:
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:805 train_function *
return step_function(self, iterator)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:795 step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py:1259 run
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py:2730 call_for_each_replica
return self._call_for_each_replica(fn, args, kwargs)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py:3417 _call_for_each_replica
return fn(*args, **kwargs)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:788 run_step **
outputs = model.train_step(data)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:755 train_step
loss = self.compiled_loss(
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/keras/engine/compile_utils.py:203 __call__
loss_value = loss_obj(y_t, y_p, sample_weight=sw)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/keras/losses.py:152 __call__
losses = call_fn(y_true, y_pred)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/keras/losses.py:256 call **
return ag_fn(y_true, y_pred, **self._fn_kwargs)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/util/dispatch.py:201 wrapper
return target(*args, **kwargs)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/keras/losses.py:1537 categorical_crossentropy
return K.categorical_crossentropy(y_true, y_pred, from_logits=from_logits)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/util/dispatch.py:201 wrapper
return target(*args, **kwargs)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/keras/backend.py:4833 categorical_crossentropy
target.shape.assert_is_compatible_with(output.shape)
/Users/nicolas/.virtualenvs/cv/lib/python3.8/site-packages/tensorflow/python/framework/tensor_shape.py:1134 assert_is_compatible_with
raise ValueError("Shapes %s and %s are incompatible" % (self, other))
ValueError: Shapes (None, None) and (None, 224, 224, 1) are incompatible
Hope you guys can help me to point me in the right direction to solve the issue.
Thank you for taking some time to read the post!
EDIT-1:
The following is the code of the model to be trained. I fixed the dimension problem.
from keras.layers import concatenate
img_shape = (224,224,3)
img_top = Input(shape=img_shape)
img_bottom = Input(shape=img_shape)
featureExtractor = vgg(img_shape)
feats_top = featureExtractor(img_top)
feats_bottom = featureExtractor(img_bottom)
combined = concatenate([feats_top,feats_bottom])
x = Dense(4096, activation='relu')(combined)
x = Dense(4096, activation='relu')(x)
x = Dense(4096, activation='relu')(x)
x = Dense(2, activation='softmax')(x)
model = Model(inputs=[img_top,img_bottom], outputs=x)

how to switch to another optimizer in tensorflow?

I would like to change optimizer in the middle of training.
I use the code from this post:
Changing optimizer in keras during training
as follows:
model = Model(inputs=inputs, outputs=conv12)
def rmse(y_true, y_pred):
return backend.sqrt(backend.mean(backend.square(y_pred - y_true)))#, axis=-1))
class OptimizerChanger(EarlyStopping):
def __init__(self, on_train_end, **kwargs):
self.do_on_train_end = on_train_end
super(OptimizerChanger, self).__init__(**kwargs)
def on_train_end(self, logs=None):
super(OptimizerChanger, self).on_train_end(self, logs)
self.do_on_train_end()
def do_after_training():
model.compile(optimizer='sgd', loss='mean_squared_error', metrics=['mae', rmse])
model.fit(x_train_n, y_train_n, batch_size=10, epochs=200, validation_split=0.05, shuffle=True)
changer = OptimizerChanger(on_train_end= do_after_training,
monitor='val_rmse',
min_delta=5,
patience=10)
model.compile(loss='mean_squared_error',
optimizer='adam',
metrics=['mae', rmse])
history = model.fit(x_train_n, y_train_n, batch_size=10, epochs=200, validation_split=0.05, shuffle=True, callbacks=[changer])
I get the following error:
super(OptimizerChanger, self).on_train_end(self, logs)
TypeError: on_train_end() takes from 1 to 2 positional arguments but 3 were given
what is the third parameter that is being passed? is it implicit? how do I call it?
You're calling the method from an instance and you are passing self to it. So it's redundant.
super(OptimizerChanger, self).on_train_end(self, logs)
This line should be
super(OptimizerChanger, self).on_train_end(logs)

Why the keras code get error messages when changing from Keras 1.2.2 to Keras 2.0.5

This is a piece of code I get from github for hierarchical attention network,the code is originally in Keras 1.2.2. now I have to change it to compile with Keras 2.0.5, however, it has such error messages that I could not solve.
The original code is the following
MAX_SENT_LENGTH = 100
MAX_SENTS = 20
MAX_NB_WORDS = 276176
EMBEDDING_DIM = 128
VALIDATION_SPLIT = 0.1
# Feed the data
# Here you have source data
x_train = np.load('./data/X_full_train_data.npy')
y_train = np.load('./data/X_full_train_labels.npy')
x_val = np.load('./data/X_full_test_data.npy')
y_val = np.load('./data/X_full_test_labels.npy')
np.random.seed(10)
shuffle_indices = np.random.permutation(np.arange(len(y_train)))
x_train = x_train[shuffle_indices]
y_train = y_train[shuffle_indices]
shuffle_indices = np.random.permutation(np.arange(len(y_val)))
x_val = x_train[shuffle_indices]
y_val = y_train[shuffle_indices]
with open("./data/W.npy", "rb") as fp:
embedding_weights = np.load(fp)
# here you feed embeding matrix
embedding_layer = Embedding(MAX_NB_WORDS,
EMBEDDING_DIM,
weights=[embedding_weights],
input_length=MAX_SENT_LENGTH,
trainable=True)
# building Hierachical Attention network
class AttLayer(Layer):
def __init__(self, **kwargs):
self.init = initializers.get('normal')
super(AttLayer, self).__init__(**kwargs)
def build(self, input_shape):
assert len(input_shape)==3
self.W = self.init((input_shape[-1],))
self.trainable_weights = [self.W]
super(AttLayer, self).build(input_shape)
def call(self, x, mask=None):
eij = K.tanh(K.dot(x, self.W))
ai = K.exp(eij)
weights = ai/K.sum(ai, axis=1).dimshuffle(0,'x')
weighted_input = x*weights.dimshuffle(0,1,'x')
ret = weighted_input.sum(axis=1)
return ret
#def get_output_shape_for(self, input_shape):
def compute_output_shape(self,input_shape):
return (input_shape[0], input_shape[-1])
sentence_input = Input(shape=(MAX_SENT_LENGTH,), dtype='int32')
embedded_sequences = embedding_layer(sentence_input)
l_lstm = Bidirectional(GRU(100, return_sequences=True))(embedded_sequences)
l_dense = TimeDistributed(Dense(200))(l_lstm)
l_att = AttLayer()(l_lstm)
sentEncoder = Model(sentence_input, l_att)
review_input = Input(shape=(MAX_SENTS,MAX_SENT_LENGTH), dtype='int32')
review_encoder = TimeDistributed(sentEncoder)(review_input)
l_lstm_sent = Bidirectional(GRU(100, return_sequences=True))(review_encoder)
l_dense_sent = TimeDistributed(Dense(200))(l_lstm_sent)
l_att_sent = AttLayer()(l_lstm_sent)
preds = Dense(3, activation='softmax')(l_att_sent)
model = Model(input=review_input, output=preds)
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['categorical_accuracy'])
print("model fitting - Hierachical attention network")
print(model.summary())
model.fit(x_train, y_train, nb_epoch=10, batch_size=32, validation_data=(x_val,y_val))
predictions = model.predict(x_val)
score, acc = model.evaluate(x_val, y_val,batch_size=32)
Then I have the following error
textClassifierHATT.py:235: UserWarning: The `nb_epoch` argument in `fit` has been renamed `epochs`.
model.fit(x_train, y_train, nb_epoch=10, batch_size=32, validation_data=(x_val,y_val))
Traceback (most recent call last):
File "textClassifierHATT.py", line 235, in <module>
model.fit(x_train, y_train, nb_epoch=10, batch_size=32, validation_data=(x_val,y_val))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training.py", line 1575, in fit
self._make_train_function()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training.py", line 960, in _make_train_function
loss=self.total_loss)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/legacy/interfaces.py", line 87, in wrapper
return func(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/optimizers.py", line 226, in get_updates
accumulators = [K.zeros(K.int_shape(p), dtype=K.dtype(p)) for p in params]
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/optimizers.py", line 226, in <listcomp>
accumulators = [K.zeros(K.int_shape(p), dtype=K.dtype(p)) for p in params]
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/backend/theano_backend.py", line 275, in int_shape
raise TypeError('Not a Keras tensor:', x)
TypeError: ('Not a Keras tensor:', Elemwise{add,no_inplace}.0)
the keras model compile succesfully in model.compile(), but it has error in model.fit(), I totally don't understand why such error exists. anyone can tell me how to modify it so that it can run with keras 2.0 Thanks a lot.
The problem is on the build method of your custom layer, according to keras' documentation, you need to create the weights with the self.add_weight function:
def build(self, input_shape):
assert len(input_shape)==3
self.W = self.add_weight(name='kernel',
shape=(input_shape[-1],),
initializer='normal',
trainable=True)
super(AttLayer, self).build(input_shape)
That and a few API changes:
Parameter input and output changed in Model(inputs=.., outputs=..)
The nb_epochs parameter in fit is now called epochs
The data provided for training is not a tensor but fed as a numpy array. Try to convert the numpy arrays to tensor using :
import tensorflow as tf
tf.convert_to_tensor(
value, dtype=None, dtype_hint=None, name=None
)
Then pass them to the model for training.

Categories