2020-01-01 23:24:08 -07:00
|
|
|
#!/usr/bin/python3
|
2020-01-02 16:07:25 -07:00
|
|
|
# wut-ml
|
2020-01-02 22:51:51 -07:00
|
|
|
#
|
|
|
|
# Vet a SatNOGS image using machine learning (guessing).
|
|
|
|
# It will vet the image located at test/unvetted/waterfall.png.
|
|
|
|
#
|
|
|
|
# Note, there is an issue to fix where it will vet everything
|
2020-01-03 18:13:37 -07:00
|
|
|
# under the data/test directory, so fix that. For now, just delete
|
2020-01-02 22:51:51 -07:00
|
|
|
# everything else. :)
|
|
|
|
#
|
|
|
|
# Usage:
|
|
|
|
# wut-ml
|
|
|
|
# Example:
|
|
|
|
# wut-ml
|
2020-01-02 11:53:15 -07:00
|
|
|
|
2020-01-01 23:24:08 -07:00
|
|
|
import os
|
|
|
|
import numpy as np
|
|
|
|
import tensorflow.python.keras
|
|
|
|
from tensorflow.python.keras import Sequential
|
|
|
|
from tensorflow.python.keras.layers import Activation, Dropout, Flatten, Dense
|
|
|
|
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator
|
|
|
|
from tensorflow.python.keras.layers import Convolution2D, MaxPooling2D, ZeroPadding2D
|
|
|
|
from tensorflow.python.keras import optimizers
|
|
|
|
from tensorflow.python.keras.preprocessing import image
|
|
|
|
from tensorflow.python.keras.models import load_model
|
|
|
|
from tensorflow.python.keras.preprocessing.image import load_img
|
|
|
|
from tensorflow.python.keras.preprocessing.image import img_to_array
|
|
|
|
|
2020-01-04 18:36:35 -07:00
|
|
|
# XXX
|
|
|
|
from tensorflow.python.keras.models import Model
|
|
|
|
from tensorflow.python.keras.layers import Input, concatenate
|
|
|
|
#from tensorflow.python.keras.optimizers import Adam
|
|
|
|
|
|
|
|
|
|
|
|
# XXX Plot
|
|
|
|
from tensorflow.python.keras.utils import plot_model
|
|
|
|
from tensorflow.python.keras.callbacks import ModelCheckpoint
|
|
|
|
## for visualizing
|
|
|
|
import matplotlib.pyplot as plt, numpy as np
|
|
|
|
from sklearn.decomposition import PCA
|
|
|
|
|
2020-01-04 15:40:46 -07:00
|
|
|
# https://keras.io/preprocessing/image/
|
2020-01-04 18:36:35 -07:00
|
|
|
# TODO:
|
|
|
|
# * Pre-process image
|
2020-01-04 15:40:46 -07:00
|
|
|
print("datagen")
|
2020-01-04 15:19:22 -07:00
|
|
|
datagen = ImageDataGenerator(
|
|
|
|
featurewise_center=False,
|
|
|
|
samplewise_center=False,
|
|
|
|
featurewise_std_normalization=False,
|
|
|
|
samplewise_std_normalization=False,
|
|
|
|
zca_whitening=False,
|
|
|
|
zca_epsilon=1e-06,
|
|
|
|
rescale=1./255,
|
|
|
|
shear_range=0.0,
|
|
|
|
zoom_range=0.0,
|
|
|
|
rotation_range=0,
|
|
|
|
width_shift_range=0.0,
|
|
|
|
height_shift_range=0.0,
|
|
|
|
brightness_range=None,
|
|
|
|
channel_shift_range=0.0,
|
|
|
|
fill_mode='nearest',
|
|
|
|
cval=0.0,
|
|
|
|
horizontal_flip=False,
|
|
|
|
vertical_flip=False,
|
|
|
|
preprocessing_function=None,
|
|
|
|
data_format='channels_last',
|
|
|
|
validation_split=0.0,
|
|
|
|
dtype='float32')
|
|
|
|
|
2020-01-04 15:40:46 -07:00
|
|
|
print("datagen.flow")
|
2020-01-01 23:24:08 -07:00
|
|
|
train_it = datagen.flow_from_directory('data/train/', class_mode='binary')
|
2020-01-02 19:28:26 -07:00
|
|
|
val_it = datagen.flow_from_directory('data/val/', class_mode='binary')
|
2020-01-01 23:24:08 -07:00
|
|
|
test_it = datagen.flow_from_directory('data/test/', class_mode='binary')
|
2020-01-04 18:36:35 -07:00
|
|
|
|
2020-01-04 15:40:46 -07:00
|
|
|
print("train_it.next()")
|
2020-01-04 18:36:35 -07:00
|
|
|
trainX, trainY = train_it.next()
|
|
|
|
print('Batch shape=%s, min=%.3f, max=%.3f' % (trainX.shape, trainX.min(), trainX.max()))
|
|
|
|
valX, valY = val_it.next()
|
|
|
|
print('Batch shape=%s, min=%.3f, max=%.3f' % (valX.shape, valX.min(), valX.max()))
|
|
|
|
testX, testY = test_it.next()
|
|
|
|
print('Batch shape=%s, min=%.3f, max=%.3f' % (testX.shape, testX.min(), testX.max()))
|
|
|
|
|
|
|
|
print("input shape")
|
|
|
|
input_shape=trainX.shape[1:]
|
|
|
|
print(input_shape)
|
|
|
|
|
2020-01-04 14:12:51 -07:00
|
|
|
#img_width=823
|
|
|
|
#img_height=1606
|
2020-01-01 23:24:08 -07:00
|
|
|
img_width=256
|
|
|
|
img_height=256
|
2020-01-04 15:40:46 -07:00
|
|
|
print("Height", img_height, "Width", img_width)
|
|
|
|
|
|
|
|
# https://keras.io/models/sequential/
|
|
|
|
# https://keras.io/getting-started/sequential-model-guide/
|
|
|
|
print("Sequential")
|
2020-01-01 23:24:08 -07:00
|
|
|
model = Sequential()
|
2020-01-04 15:40:46 -07:00
|
|
|
|
|
|
|
print("add")
|
2020-01-04 18:36:35 -07:00
|
|
|
# Other data to consider adding:
|
|
|
|
# * JSON metadata
|
|
|
|
# * TLE
|
|
|
|
# * Audio File (ogg)
|
2020-01-06 15:35:22 -07:00
|
|
|
# https://www.tensorflow.org/io/api_docs/python/tfio/ffmpeg/AudioDataset
|
2020-01-04 18:36:35 -07:00
|
|
|
# * Decoded Data (HEX, ASCII, PNG)
|
|
|
|
# Data from external sources to consider adding:
|
|
|
|
# * Weather
|
|
|
|
|
|
|
|
print("convolution 2 deeeee")
|
2020-01-04 15:40:46 -07:00
|
|
|
# https://keras.io/layers/convolutional/
|
2020-01-04 18:36:35 -07:00
|
|
|
#model.add(Convolution2D(32, 3, 3, input_shape=trainX.shape[1:]))
|
|
|
|
#model.add(Convolution2D(32, 3, 3, input_shape=(255,255,3)))
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(Convolution2D(32, 3, 3, input_shape=(img_width, img_height,3)))
|
2020-01-04 15:40:46 -07:00
|
|
|
# https://keras.io/activations/
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Activation relu")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(Activation('relu'))
|
2020-01-04 15:40:46 -07:00
|
|
|
# https://keras.io/layers/pooling/
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Pooling")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(MaxPooling2D(pool_size=(2, 2)))
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Convolution2D")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(Convolution2D(32, 3, 3))
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Activation relu")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(Activation('relu'))
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Pooling")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(MaxPooling2D(pool_size=(2, 2)))
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Convolution2D")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(Convolution2D(64, 3, 3))
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Activation relu")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(Activation('relu'))
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Pooling")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(MaxPooling2D(pool_size=(2, 2)))
|
2020-01-04 15:40:46 -07:00
|
|
|
# https://keras.io/layers/core/
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Flatten")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(Flatten())
|
2020-01-04 15:40:46 -07:00
|
|
|
# https://keras.io/layers/core/
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Dense")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(Dense(64))
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Activation relu")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(Activation('relu'))
|
2020-01-04 15:40:46 -07:00
|
|
|
# https://keras.io/layers/core/
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Dropout")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(Dropout(0.5))
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Dense")
|
2020-01-01 23:24:08 -07:00
|
|
|
model.add(Dense(1))
|
2020-01-04 18:36:35 -07:00
|
|
|
print("Activation softmax")
|
2020-01-04 13:35:09 -07:00
|
|
|
model.add(Activation('softmax'))
|
2020-01-04 15:40:46 -07:00
|
|
|
|
|
|
|
# https://keras.io/models/sequential/
|
|
|
|
print("compile")
|
2020-01-04 15:19:22 -07:00
|
|
|
model.compile(
|
|
|
|
loss='categorical_crossentropy',
|
|
|
|
loss_weights=None,
|
|
|
|
sample_weight_mode=None,
|
|
|
|
weighted_metrics=None,
|
|
|
|
target_tensors=None,
|
|
|
|
optimizer='rmsprop',
|
|
|
|
metrics=['accuracy'])
|
|
|
|
|
2020-01-04 18:36:35 -07:00
|
|
|
|
|
|
|
|
2020-01-04 15:40:46 -07:00
|
|
|
# https://keras.io/models/sequential/
|
|
|
|
print("fit")
|
2020-01-04 15:19:22 -07:00
|
|
|
model.fit(
|
|
|
|
x=train_it,
|
|
|
|
y=None,
|
2020-01-04 15:40:46 -07:00
|
|
|
batch_size=None,
|
|
|
|
epochs=1,
|
2020-01-04 15:19:22 -07:00
|
|
|
verbose=2,
|
2020-01-04 15:40:46 -07:00
|
|
|
callbacks=None,
|
|
|
|
validation_split=0.0,
|
|
|
|
validation_data=val_it,
|
|
|
|
shuffle=True,
|
|
|
|
class_weight=None,
|
|
|
|
sample_weight=None,
|
|
|
|
initial_epoch=0,
|
|
|
|
steps_per_epoch=None,
|
|
|
|
validation_steps=None,
|
|
|
|
validation_freq=1,
|
|
|
|
max_queue_size=10,
|
2020-01-04 15:19:22 -07:00
|
|
|
workers=16,
|
|
|
|
use_multiprocessing=True)
|
|
|
|
|
2020-01-04 15:40:46 -07:00
|
|
|
# https://keras.io/models/sequential/
|
2020-01-04 15:19:22 -07:00
|
|
|
# evaluate(x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None, callbacks=None, max_queue_size=10, workers=1, use_multiprocessing=False)
|
2020-01-01 23:24:08 -07:00
|
|
|
|
2020-01-04 18:36:35 -07:00
|
|
|
# TODO:
|
|
|
|
# * Generate output to visualize training/validating/testing.
|
|
|
|
# Plot, fail
|
|
|
|
#print("plot")
|
|
|
|
#plot_model(test_it, to_file='data/wut-plot.png', show_shapes=True, show_layer_names=True)
|
|
|
|
|
2020-01-04 15:40:46 -07:00
|
|
|
# https://keras.io/models/sequential/
|
|
|
|
print("predict")
|
2020-01-04 15:19:22 -07:00
|
|
|
prediction = model.predict(
|
|
|
|
x=test_it,
|
|
|
|
batch_size=None,
|
|
|
|
verbose=2,
|
|
|
|
steps=None,
|
|
|
|
callbacks=None,
|
|
|
|
max_queue_size=10,
|
|
|
|
workers=16,
|
|
|
|
use_multiprocessing=True)
|
2020-01-03 23:42:31 -07:00
|
|
|
|
2020-01-02 11:48:06 -07:00
|
|
|
print(prediction)
|
2020-01-01 23:24:08 -07:00
|
|
|
|
|
|
|
if prediction[0][0] == 1:
|
|
|
|
rating = 'bad'
|
2020-01-02 20:56:16 -07:00
|
|
|
else:
|
|
|
|
rating = 'good'
|
2020-01-01 23:24:08 -07:00
|
|
|
print('Observation: %s' % (rating))
|
|
|
|
|