File size: 3,109 Bytes
3a3c68a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
from typing import Any
import keras
from helpers import *
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv3D, LSTM, Dense, Dropout, Bidirectional, MaxPool3D, Activation, Reshape, SpatialDropout3D, BatchNormalization, TimeDistributed, Flatten
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import ModelCheckpoint, LearningRateScheduler
class Predictor(keras.Model):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.model = self.create_model()
@classmethod
def create_model(cls):
model = Sequential()
model.add(Conv3D(128, 3, input_shape=(75, 46, 140, 1), padding='same'))
model.add(Activation('relu'))
model.add(MaxPool3D((1, 2, 2)))
model.add(Conv3D(256, 3, padding='same'))
model.add(Activation('relu'))
model.add(MaxPool3D((1, 2, 2)))
model.add(Conv3D(75, 3, padding='same'))
model.add(Activation('relu'))
model.add(MaxPool3D((1, 2, 2)))
model.add(TimeDistributed(Flatten()))
model.add(Bidirectional(LSTM(
128, kernel_initializer='Orthogonal', return_sequences=True
)))
model.add(Dropout(.5))
model.add(Bidirectional(LSTM(
128, kernel_initializer='Orthogonal', return_sequences=True
)))
model.add(Dropout(.5))
model.add(Dense(
char_to_num.vocabulary_size() + 1,
kernel_initializer='he_normal',
activation='softmax'
))
return model
def call(self, *args, **kwargs):
return self.model.call(*args, **kwargs)
@classmethod
def scheduler(cls, epoch, lr):
if epoch < 30:
return lr
else:
return lr * tf.math.exp(-0.1)
@classmethod
def CTCLoss(cls, y_true, y_pred):
batch_len = tf.cast(tf.shape(y_true)[0], dtype="int64")
input_length = tf.cast(tf.shape(y_pred)[1], dtype="int64")
label_length = tf.cast(tf.shape(y_true)[1], dtype="int64")
input_length = input_length * tf.ones(shape=(batch_len, 1), dtype="int64")
label_length = label_length * tf.ones(shape=(batch_len, 1), dtype="int64")
loss = tf.keras.backend.ctc_batch_cost(
y_true, y_pred, input_length, label_length
)
return loss
class ProduceExample(tf.keras.callbacks.Callback):
def __init__(self, dataset) -> None:
self.dataset = dataset.as_numpy_iterator()
def on_epoch_end(self, epoch, logs=None) -> None:
data = self.dataset.next()
yhat = self.model.predict(data[0])
decoded = tf.keras.backend.ctc_decode(
yhat, [75, 75], greedy=False
)[0][0].numpy()
for x in range(len(yhat)):
print('Original:', tf.strings.reduce_join(
num_to_char(data[1][x])
).numpy().decode('utf-8'))
print('Prediction:', tf.strings.reduce_join(
num_to_char(decoded[x])
).numpy().decode('utf-8'))
print('~' * 100) |