2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

気温と気圧配置図から季節を予測する

Last updated at Posted at 2022-01-24

#はじめに
以前、地図上にデータをプロットしたり、cifar10で分類をさせてみたりしましたが、今回はそれを組み合わせてやろうという思いつきで始めてみました。要するに、既存のデータセットではなく自作データでやってみようというわけです。

###目次
・使用したもの
・画像データの作成
・訓練データ、テストデータの作成
・識別機に放り込む

###使用したもの

import cartopy.crs as ccrs 
import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib import cm 
from PIL import Image 
from tensorflow.keras.utils import to_categorical

いろいろimportしているときなんかワクワクするの私だけでしょうか。

###画像データの作成
まず、日本周辺の気温と気圧配置の図をcartopyを使って作成しました。その点は、使っているデータセットによるのでコードは割愛します。
pic.png
このような画像データを3年分、365*3枚の画像を作成しました。

###訓練データ、テストデータの作成
保存したままのデータだと(4000, 4000, 4)のデータで、一度に乗せることができなかったので解像度を荒くしていきます。画像データがpic_0.pngとして保存されているとすると

from PIL import Image 
img = Image.open(f'pic_0.png')
img = img.resize((300, 300))

(300, 300, 4)まで落とすことができました。これを全データで行いました。ここから、訓練データとテストデータを作っていきます。画像1年分は1月から365日分12月までです。また、冬を0、春を1、夏を2、秋を3としてラベルを振り当てます。

import numpy as np 
from tensorflow.keras.utils import to_categorical

x_all = np.zeros((365*3, 300, 300, 4))
y_all = np.zeros((365*3, 1))

for y in range(3):
  for i in range(365*3):
    k = y * 365
    img = Image.open(f'pic_{i+k}.png')
    img = img.resize((300, 300))
    x_all[i+k, :, :, :] = img
    if i < 59+k:
       y_all[k+d, :] = 0
    elif 59+k <= d < 151+k:
        y_all[k+d, :] = 1
    elif 151+k <= d < 243+k:
        y_all[k+d, :] = 2
    elif 243+k <= d < 334+k:
        y_all[k+d, :] = 3
    else:
        y_all[k+d, :] = 0

x_test = x_all[:250, :, :, :].astype('float32') / 255
x_train = x_all[250:, :, :, :].astype('float32') / 255
y_test = to_categorical(y_all[:250, :], 4)
y_train = to_categorical(y_all[250:, :], 4)

np.savez(f'season_data.npz', x_train=x_train, x_test=x_test, y_train=y_train, y_test=y_test)

訓練するたびにこれを実行するのはめんどくさいので保存。これで準備ができました。

###識別機に放り込む

識別機自体は以前作成したのでこちらから

[cifar10のkerasでの分類にチャレンジ]
https://qiita.com/white_coffee/items/bda12686ff490934caed

コード以下の通りです。

from tensorflow.keras.models import Model 
from tensorflow.keras.optimizers import Adam 
from tensorflow.keras.layers import Input, Dense, BatchNormalization, Dropout, Conv2D, LeakyReLU, Flatten

class discri():
    def __init__(self, input_dim, fil, ker, stri, use_batch, use_dropout, lr):
        self.input_dim = input_dim 
        self.fil = fil 
        self.ker = ker 
        self.stri = stri 
        self.name = 'discri'
        self.n_layers = len(fil)
        self.use_batch = use_batch
        self.use_dropout = use_dropout
        self.lr = lr 
        
        self.build()
    
    def build(self):
        input_layer = Input(shape=self.input_dim)
        x = input_layer
        for i in range(self.n_layers):
            conv = Conv2D(filters=self.fil[i], kernel_size=self.ker[i], strides=self.stri[i], 
            padding='same', name='conv_'+str(i))
            x = conv(x)
            if self.use_batch:
                x = BatchNormalization(momentum=self.use_batch)(x)
            x = LeakyReLU()(x)
            if self.use_dropout:
                x = Dropout(rate=0.5)(x)
        x = Flatten()(x)
        x = Dense(units=4, activation='sigmoid')(x)
        output_layer = x
        self.model = Model(input_layer, output_layer)
    
    def compile(self, lr):
        self.model.compile(optimizer=Adam(lr=lr), loss='categorical_crossentropy', metrics=['accuracy'])
    
    def train(self, data1, data2, batch_size, epochs):
        self.model.fit(data1, data2, batch_size=batch_size, epochs=epochs, shuffle='True')

各値を以下のように設定。

indim = (300, 300, 4)
filter = [300, 600, 600, 300]
kernel = [3, 3, 3, 3]
stri = [3, 3, 3, 2]
usebatch = None
usedrop = True 
Lr = 0.0005 
Epochs = 10 
Batchsize = 32

最初の入力の次元、フィルターの数を変更。動物の顔等と違いそこまで細かく見なくても大丈夫かなと思いストライドは3と2でやってみることに、Batchsizeは前回のまま変え忘れました。

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.image as mpimg 
out = np.load(f'season_data.npz')
x_train = out['x_train']
x_test = out['x_test']
y_train = out['y_train']
y_test = out['y_test']

DISCRI = discri(input_dim=indim, fil=filter, ker=kernel, stri=stri, \
    use_batch=usebatch, use_dropout=usedrop, lr=Lr)
DISCRI.model.summary()
DISCRI.compile(lr=Lr)

DISCRI.train(data1=x_train, data2=y_train, batch_size=Batchsize, epochs=Epochs)

データを呼び出しいざ実行。
Screenshot from 2022-01-23 15-44-26.png

確かめてみましょう。

y = DISCRI.model.predict(x_test)
season_list = {0:'winter', 1:'spring', 2:'summer', 3:'autumn'}
y.shape
fig = plt.figure(1, figsize=(20, 10), dpi=300, facecolor='white')
ax = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
for i in range(10):
    n = 24 * i
    img = x_test[n, :, :, :]
    name = season_list[np.argmax(y[n, :])]
    name2 = season_list[np.argmax(y_test[n, :])]
    ax[i] = fig.add_subplot(2, 5, i+1)
    ax[i].axis('off')
    ax[i].set_title('pred={0:}, actual={1:}'.format(name, name2))
    ax[i].imshow(img)
 
plt.show()

season_pred.png

いい感じ予測できてる気がしますが、やはり季節の変わり目、そして秋と春の違いは難しいみたいですね。やっぱkeras 楽しい。

###参考文献

[生成Deep Learning]
・David foster 著 
・松田晃一、小沼千絵 訳
・オライリージャパン
・2020年発行

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?