Train LSTM autoencoders with Google Colab
Article directory
Reference tutorial:
Kaggle data set uploaded to Google Colab
How to import the data in Kaggle to the colab provided by Google
1. Import the dataset to Google Colab
The method of importing data sets used in this section is to use Kaggle to solve the problem of slow data upload by Google Colab.
(1) Upload the dataset to Kaggle
If the data set used does not exist on kaggle, then you need to upload the data set to your own kaggle account.
① Prepare the data set and compress it
② Upload the compressed data set to kaggle
(2) Upload the dataset to Google Colab
①Find your kaggle account avatar and click Account
②Find Create New API Token on the page, click to download a json file
③Open the json file with Notepad and copy the contents inside
④ API for copying datasets
Find the three dots on the right, click on it, and click Copy API command
⑤Download the dataset in Google Colab
Since the Google Colab notebook is closed, the temporary data will be cleaned up. If you don’t want to be cleaned up, it is recommended to download the data to MyDrive and set the working path to MyDrive. In order to facilitate organization, I created a file called lstmautoencoder under MyDrive folder to store the dataset and model files for this project.
After completing the above steps, set the current path to the path of this folder:
cd /content/drive/MyDrive/lstmautoencoder
Then paste the copied API command to the fifth line of the code, don't forget to add an exclamation point "!" before the API command
The complete code is as follows (you need to insert the content of the json file into the third line of code in advance):
!pip install -U -q kaggle
!mkdir -p ~/.kaggle
!echo '{"username":"xxx","key":"xxx"}' > ~/.kaggle/kaggle.json
!chmod 600 ~/.kaggle/kaggle.json
!kaggle datasets download -d hashemsellat/ucsddataset
Finally, click to run this code, and the data set can be downloaded to Google Colab at a speed of more than 100 MB/s, which is very fast.
(3), data set decompression
Reference tutorial:
If the dataset downloaded to Google Colab is still in the form of a compressed package, it may need to be decompressed. The code is as follows:
import zipfile
z=zipfile.ZipFile('/content/drive/MyDrive/lstmautoencoder/ucsddataset.zip','r') # 需要解压的文件的路径
z.extractall(path=r'/content/drive/MyDrive/lstmautoencoder') # 解压到的路径
z.close
Two, run the code
Code source:
Anomaly Detection in Videos using LSTM Convolutional Autoencoder
Run the following code block by block:
!pip install keras-layer-normalization
class Config:
DATASET_PATH = "/content/drive/MyDrive/lstmautoencoder/UCSD_Anomaly_Dataset.v1p2/UCSDped1/Train"
SINGLE_TEST_PATH = "/content/drive/MyDrive/lstmautoencoder/UCSD_Anomaly_Dataset.v1p2/UCSDped1/Test/Test032"
BATCH_SIZE = 4
EPOCHS = 3
MODEL_PATH = "/content/drive/MyDrive/lstmautoencoder/model.hdf5"
from os import listdir
from os.path import isfile, join, isdir
from PIL import Image
import numpy as np
import shelve
def get_clips_by_stride(stride, frames_list, sequence_size):
""" For data augmenting purposes.
Parameters
----------
stride : int
The desired distance between two consecutive frames
frames_list : list
A list of sorted frames of shape 256 X 256
sequence_size: int
The size of the desired LSTM sequence
Returns
-------
list
A list of clips , 10 frames each
"""
clips = []
sz = len(frames_list)
clip = np.zeros(shape=(sequence_size, 256, 256, 1))
cnt = 0
for start in range(0, stride):
for i in range(start, sz, stride):
clip[cnt, :, :, 0] = frames_list[i]
cnt = cnt + 1
if cnt == sequence_size:
clips.append(np.copy(clip))
cnt = 0
return clips
def get_training_set():
"""
Returns
-------
list
A list of training sequences of shape (NUMBER_OF_SEQUENCES,SINGLE_SEQUENCE_SIZE,FRAME_WIDTH,FRAME_HEIGHT,1)
"""
#####################################
# cache = shelve.open(Config.CACHE_PATH)
# return cache["datasetLSTM"]
#####################################
clips = []
# loop over the training folders (Train000,Train001,..)
for f in sorted(listdir(Config.DATASET_PATH)):
if isdir(join(Config.DATASET_PATH, f)):
all_frames = []
# loop over all the images in the folder (0.tif,1.tif,..,199.tif)
for c in sorted(listdir(join(Config.DATASET_PATH, f))):
if str(join(join(Config.DATASET_PATH, f), c))[-3:] == "tif":
img = Image.open(join(join(Config.DATASET_PATH, f), c)).resize((256, 256))
img = np.array(img, dtype=np.float32) / 256.0
all_frames.append(img)
# get the 10-frames sequences from the list of images after applying data augmentation
for stride in range(1, 3):
clips.extend(get_clips_by_stride(stride=stride, frames_list=all_frames, sequence_size=10))
return clips
import keras
from keras.layers import Conv2DTranspose, ConvLSTM2D, BatchNormalization, TimeDistributed, Conv2D, LayerNormalization
from keras.models import Sequential, load_model
def get_model(reload_model=True):
"""
Parameters
----------
reload_model : bool
Load saved model or retrain it
"""
if not reload_model:
return load_model(Config.MODEL_PATH,custom_objects={
'LayerNormalization': LayerNormalization})
training_set = get_training_set()
training_set = np.array(training_set)
training_set = training_set.reshape(-1,10,256,256,1)
seq = Sequential()
seq.add(TimeDistributed(Conv2D(128, (11, 11), strides=4, padding="same"), batch_input_shape=(None, 10, 256, 256, 1)))
seq.add(LayerNormalization())
seq.add(TimeDistributed(Conv2D(64, (5, 5), strides=2, padding="same")))
seq.add(LayerNormalization())
# # # # #
seq.add(ConvLSTM2D(64, (3, 3), padding="same", return_sequences=True))
seq.add(LayerNormalization())
seq.add(ConvLSTM2D(32, (3, 3), padding="same", return_sequences=True))
seq.add(LayerNormalization())
seq.add(ConvLSTM2D(64, (3, 3), padding="same", return_sequences=True))
seq.add(LayerNormalization())
# # # # #
seq.add(TimeDistributed(Conv2DTranspose(64, (5, 5), strides=2, padding="same")))
seq.add(LayerNormalization())
seq.add(TimeDistributed(Conv2DTranspose(128, (11, 11), strides=4, padding="same")))
seq.add(LayerNormalization())
seq.add(TimeDistributed(Conv2D(1, (11, 11), activation="sigmoid", padding="same")))
print(seq.summary())
seq.compile(loss='mse', optimizer=keras.optimizers.Adam(lr=1e-4, decay=1e-5, epsilon=1e-6))
seq.fit(training_set, training_set,
batch_size=Config.BATCH_SIZE, epochs=Config.EPOCHS, shuffle=False)
seq.save(Config.MODEL_PATH)
return seq
def get_single_test():
sz = 200
test = np.zeros(shape=(sz, 256, 256, 1))
cnt = 0
for f in sorted(listdir(Config.SINGLE_TEST_PATH)):
if str(join(Config.SINGLE_TEST_PATH, f))[-3:] == "tif":
img = Image.open(join(Config.SINGLE_TEST_PATH, f)).resize((256, 256))
img = np.array(img, dtype=np.float32) / 256.0
test[cnt, :, :, 0] = img
cnt = cnt + 1
return test
import matplotlib.pyplot as plt
def evaluate():
model = get_model(False)
print("got model")
test = get_single_test()
print(test.shape)
sz = test.shape[0] - 10 + 1
sequences = np.zeros((sz, 10, 256, 256, 1))
# apply the sliding window technique to get the sequences
for i in range(0, sz):
clip = np.zeros((10, 256, 256, 1))
for j in range(0, 10):
clip[j] = test[i + j, :, :, :]
sequences[i] = clip
print("got data")
# get the reconstruction cost of all the sequences
reconstructed_sequences = model.predict(sequences,batch_size=4)
sequences_reconstruction_cost = np.array([np.linalg.norm(np.subtract(sequences[i],reconstructed_sequences[i])) for i in range(0,sz)])
sa = (sequences_reconstruction_cost - np.min(sequences_reconstruction_cost)) / np.max(sequences_reconstruction_cost)
sr = 1.0 - sa
# plot the regularity scores
plt.plot(sr)
plt.ylabel('regularity score Sr(t)')
plt.xlabel('frame t')
plt.show()
evaluate()
operation result:
got model
(200, 256, 256, 1)
got data