2022年11月29日 星期二

下一偵預測程式碼

 # ==================================================

# 彩色版使用生成器
# 不知道為什麼,使用生成器,模型的訓練就不會結束。
# ^找出原因了,我訓練參數沒有按書上寫的設定。此程式目前看起來成功了。
def TMString():

global timeI
global minuteI

if (minuteI == 160 ):
minuteI = minuteI - 60
timeI = timeI + 1
minuteS = str(minuteI)
minute = minuteS[1:3]
else:
minuteS = str(minuteI)
minute = minuteS[1:3]

timeS = str(timeI)
time = timeS[1:3]
minuteI = minuteI + 1
return (time + minute)
##

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as img

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

import io
import imageio
from IPython.display import Image, display
from ipywidgets import widgets, Layout, HBox
import cv2

import os

pathList = ["DropletTestImg0_64/20220407/20220407",
"DropletTestImg0_64/20220408/20220408",
"DropletTestImg0_64/20220409/20220409",
"DropletTestImg0_64/20220410/20220410",
"DropletTestImg0_64/20220411/20220411",
"DropletTestImg0_64/20220412/20220412",
"DropletTestImg0_64/20220413/20220413",
"DropletTestImg0_64/20220414/20220414",
"DropletTestImg0_64/20220415/20220415",
"DropletTestImg0_64/20220416/20220416",
"DropletTestImg0_64/20220417/20220417",
"DropletTestImg0_64/20220418/20220418",
"DropletTestImg0_64/20220419/20220419",
"DropletTestImg0_64/20220420/20220420",
"DropletTestImg0_64/20220421/20220421",
"DropletTestImg0_64/20220422/20220422",
"DropletTestImg0_64/20220423/20220423",
"DropletTestImg0_64/20220424/20220424",
"DropletTestImg0_64/20220425/20220425",
"DropletTestImg0_64/20220426/20220426",
"DropletTestImg0_64/20220427/20220427",
"DropletTestImg0_64/20220428/20220428",
"DropletTestImg0_64/20220509/20220509",
"DropletTestImg0_64/20220510/20220510",
"DropletTestImg0_64/20220511/20220511",
"DropletTestImg0_64/20220516/20220516",
"DropletTestImg0_64/20220517/20220517",
"DropletTestImg0_64/20220518/20220518",
"DropletTestImg0_64/20220519/20220519",
"DropletTestImg0_64/20220617/20220617",
"DropletTestImg0_64/20220618/20220618",
"DropletTestImg0_64/20220619/20220619",
"DropletTestImg0_64/20220620/20220620",
"DropletTestImg0_64/20220621/20220621",
"DropletTestImg0_64/20220622/20220622",
"DropletTestImg0_64/20220623/20220623",
"DropletTestImg0_64/20220624/20220624",
"DropletTestImg0_64/20220625/20220625",
"DropletTestImg0_64/20220626/20220626",
"DropletTestImg0_64/20220627/20220627",
"DropletTestImg0_64/20220628/20220628",
"DropletTestImg0_64/20220629/20220629",
"DropletTestImg0_64/20220630/20220630",
"DropletTestImg0_64/20220701/20220701",
"DropletTestImg0_64/20220702/20220702",
"DropletTestImg0_64/20220703/20220703",
"DropletTestImg0_64/20220705/20220705",
"DropletTestImg0_64/20220706/20220706",
"DropletTestImg0_64/20220707/20220707",
"DropletTestImg0_64/20220709/20220709",
"DropletTestImg0_64/20220710/20220710",
"DropletTestImg0_64/20220711/20220711",
"DropletTestImg0_64/20220713/20220713",
"DropletTestImg0_64/20220714/20220714"]


pen = 900 # <每個資料夾內最多能提供的照片數
frameNumber = 19
# image = np.zeros((frameNumber+1, ImgSize, ImgSize, 3)) # < 原本希望彩色
# img = np.zeros((frameNumber+1,ImgSize,ImgSize))
add = -1

# 把能夠連續 20 張為 1 組的第 0 張照片路徑找出來。
FirstPhoto = [] # <用來存路徑的列表
for i in pathList:
add = -1
j = 0
k = - 1
timeI = 105 # <代表起始 點
minuteI = 100 # <代表起始 分
while j < pen:
path = f"{i}{TMString()}00_11.jpg"
if os.path.isfile(path):
k += 1
if k == 0:
picture0 = path
print(picture0)
else:
k = -1
j += 1
if k == frameNumber:
k = -1
add += 1
FirstPhoto.append(picture0)
print(f"來源資料夾 {path[51:59]},資料數:{add+1}")

np.random.shuffle(FirstPhoto) # <洗牌,這個洗牌的奇怪之處是沒有命名其他變數指向洗過牌的變數列表物件。
print(f"每筆訓練資料都是連續20張圖,共有{len(FirstPhoto)}組,並且已經打亂!")
print("FirstPhoto列表有每組資料的首張圖檔名!")


ImgSize = 64
image = np.zeros((frameNumber+1, ImgSize, ImgSize, 3))

def create_shifted_frames(data):
x = data[:, 0: data.shape[1] - 1, :, :, :]
y = data[:, 1: data.shape[1], :, :, :]
return x, y


def trn_gen():
addMax = 5
while True:
add = 0
image = np.zeros((20, ImgSize, ImgSize, 3))
dataset = np.zeros((addMax, 20, ImgSize, ImgSize, 3))
for i in range(int(len(FirstPhoto)*0.9)):
pathW = FirstPhoto[i]
pathI = pathW[:36]
pathF = pathW[40:]
global timeI
timeI = 100+int(pathW[36:38]) # <代表起始 點
global minuteI
minuteI = 100 + int(pathW[38:40]) # <代表起始 分
#print("訓練名單開頭照片", pathW)

for j in range(20):
path = f"{pathI}{TMString()}{pathF}"
image[j, :, :, :] = img.imread(path)

# while add < addMax:
dataset[add, :, :, :, :] = image
add += 1

if add == addMax:
dataset = dataset / 255
x_train, y_train = create_shifted_frames(dataset)
add = 0
#print("x_train.shape", x_train.shape)
yield (x_train, y_train)


def val_gen():
addMax = 1
while True:
add = 0
image = np.zeros((20, ImgSize, ImgSize, 3))
dataset = np.zeros((addMax, 20, ImgSize, ImgSize, 3))
for i in range(int(len(FirstPhoto)*0.9), len(FirstPhoto)):
pathW = FirstPhoto[i]
pathI = pathW[:36]
pathF = pathW[40:]
global timeI
timeI = 100+int(pathW[36:38]) # <代表起始 點
global minuteI
minuteI = 100 + int(pathW[38:40]) # <代表起始 分
#print("驗證名單開頭照片", pathW)

for j in range(20):
path = f"{pathI}{TMString()}{pathF}"
image[j, :, :, :] = img.imread(path)

# while add < addMax:
dataset[add, :, :, :, :] = image
add += 1

if add == addMax:
dataset = dataset / 255
x_val, y_val = create_shifted_frames(dataset)
add = 0
#print("x_val.shape", x_val.shape)
yield (x_val, y_val)


# =============================================================

# 建構模型
print("準備建模")
inp = layers.Input(shape=(None, ImgSize, ImgSize, 3)) # 因為使用生成器了,所以輸入形狀得先自己訂好。

# inp = layers.Input(shape=(None, *x_train.shape[2:]))
x = layers.ConvLSTM2D(
filters=78,
kernel_size=(5, 5),
padding="same",
return_sequences=True,
activation="relu",
)(inp)
x = layers.BatchNormalization()(x)
x = layers.ConvLSTM2D(
filters=78,
kernel_size=(3, 3),
padding="same",
return_sequences=True,
activation="relu",
)(x)
x = layers.BatchNormalization()(x)
x = layers.ConvLSTM2D(
filters=78,
kernel_size=(1, 1),
padding="same",
return_sequences=True,
activation="relu",
)(x)
x = layers.Conv3D(
filters=3, kernel_size=(3, 3, 3), activation="sigmoid", padding="same"
)(x)

# Next, we will build the complete model and compile it.
model = keras.models.Model(inp, x)

model.compile(
loss=keras.losses.binary_crossentropy, optimizer=keras.optimizers.Adam(),
)
print("編譯完成")

# Define some callbacks to improve training.
early_stopping = keras.callbacks.EarlyStopping(monitor="val_loss", patience=10)
reduce_lr = keras.callbacks.ReduceLROnPlateau(monitor="val_loss", patience=5)

# Define modifiable training hyperparameters.
epochs = 20
# batch_size = 5

# Fit the model to the training data.
print("準備訓練")
model.fit(
trn_gen(),
steps_per_epoch=313,
validation_data=val_gen(),
validation_steps=174,
callbacks=[early_stopping, reduce_lr],
epochs=epochs
)
print("存檔")
model.save('AllSkyColor_01.h5')

# from google.colab import files
# files.download('conv_lstm_AllSkyGray_01.h5')