ResNetモデルを用いた株式相場予想

# はじめに

深層強化学習モデルMuZeroを開発する前段階として、ResNetモデルの実装を行なった。

ソースコードはこちら

https://github.com/sugiyama404/forecast_sp500/blob/main/ResNet.ipynb

### 関連

https://qiita.com/sugiyama404/items/49420557981b399acdf8

https://qiita.com/sugiyama404/items/9287b062dd1a69e1f7dc


## 使用データについて

トレンド傾向の掴みやすさから、yahoo financeからGSPCの日足を使用した。

訓練データの期間：2015/1/1 - 2017/6/30
テストデータの期間：2017/7/1 - 2021/1/1

以下ソースコード

https://github.com/sugiyama404/ReinfoceLearningForTrading/blob/main/get_csv.ipynb

# 時系列におけるCNN

## 一般的なCNN

　CNN(Convolutional Neural Networks)は、畳み込み層を含んだニューラルネットワークで、画像データから意味のあるデータを抽出し、画像認識などを行えるようにする。

![cnn_info.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/b058954a-e407-38a9-0f54-9299e56b53e9.png)


畳み込み層・・・入力データから特徴量を抽出する層
プーリング層・・・入力データを圧縮する層
全結合層・・・全てのニューロンが繋がった層

## 時系列におけるCNN

　CNNは、時系列データに置いて、1次元の入力データを2次元の行列に変換することで、特徴量の抽出に用いる。[^1]

![cnn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/59bfbd27-8a3b-fc48-2b8c-678059c4f91c.png)


# ResNet[^2]

一般にCNNは層を厚くすることで、複雑な特徴量を学習できるが、それに伴い性能が悪くなる。そこで、ResNet(Residual Network)では、CNNを多く重ね、ショートカットを作ることで、この問題を解決した。

![Screen Shot 2022-04-10 at 16.36.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/fc5f1173-997f-78ef-e096-319a764557bc.png)

上図は[^2]より引用


# モデル構築[^3]

![resnet-archi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/6f48d240-d191-83b5-6657-d86f9f921786.png)

上図は[^3]より引用

![muzero_model.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/15f18a11-decd-deaa-231c-23e315d9e3fd.png)


```python
class Brain:
    def __init__(self, loadmodel = False):
        self.filters = 64
        self.hidden_layers = 16
        self.obs_shape = (look_back, 1) # look_back=10
        self.nn_actions = 9
        self.kr = l2(0.0005)
        self.opt = Adam(learning_rate=0.0001, epsilon=0.001)
        self.units = 64

        if not loadmodel:
            self._main_network_layer()
        else:
            self._load()

    def _main_network_layer(self):
        x = input = Input(shape = self.obs_shape)
        arr = [[8, 5, 3, 1],[8, 5, 3, 1],[8, 5, 3]]
        filter = [self.filters, self.filters * 2, self.filters * 2]
        for a, f in zip(arr, filter):
            x = self._residual_layer(a, f)(x)

        print(x.shape) # (None, 10, 128)
        x = GlobalAveragePooling1D()(x) # (None, 128)
        x = Dense(1)(x) # (None, 1)

        model = Model(inputs = input, outputs= x)
        model.compile(loss = 'categorical_crossentropy', optimizer = self.opt, metrics=['accuracy'])
        self.model = model
        model.summary()

        dot_img_file = './resnet_model.png'
        tf.keras.utils.plot_model(model, to_file=dot_img_file, show_shapes=True)


    def _residual_layer(self, arr, filter):
        def f(input_block):
            x = input_block
            for a in arr:
                if a >=  5:
                    x = self._conv_layer(filter, a, True)(x)
                elif a == 3:
                    x = self._conv_layer(filter, a, False)(x)
                else:
                    if len(arr) == 3:
                        input_block = BatchNormalization()(input_block)
                    else:
                        input_block = self._conv_layer(filter,
                                                       a, False)(input_block)

            x = Add()([x, input_block])
            x = Activation('relu')(x)
            return x
        return f

    def _conv_layer(self, filters, kernel_size  = 1, join_act = True):
        def f(input_block):
            x = Conv1D(filters=filters, kernel_size=kernel_size,
                       padding="same")(input_block)
            x = BatchNormalization()(x)
            if join_act:
                x = Activation('relu')(x)
            return x
        return f
```

# 損失関数

![Unknown.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/070c3791-db82-a6ae-16fd-db938b232484.png)



# 学習結果

![Unknown-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/2c2c198b-51d8-9bbd-b87f-73b6b1cecca4.png)

![Unknown-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/a41b8ce4-e02f-7072-0298-83cdd7a1d871.png)



[^1]: S. Chen and H. He. Stock Prediction Using Convolutional Neural Network. Materials Science and Engineering443. 2018

[^2]: Kaiming He, Xiangyu Zhang, Shaoqing Ren and Jian Sun. Deep Residual Learning for Image Recognition. In International Conference on Machine Learning. 2015.

[^3]: Hassan Ismail Fawaz, Germain Forestier, Jonathan Weber, Lhassane Idoumghar and Pierre-Alain Muller IRIMAS, Universite ́ Haute-Alsace, Mulhouse, France. Adversarial Attacks on Deep Neural Networks for Time Series Classification. In International Conference on Machine Learning. 2019.