ImportError: cannot import name 'ops' from 'keras'の原因を予想しながら解決した話

# はじめに
Tensorflowを用いて機械学習環境を構築していた際、下記エラーに遭遇しました。
```
ImportError: cannot import name 'ops' from 'keras' (/usr/local/lib/python3.10/dist-packages/keras/__init__.py)
```

Stackoverflowではkerasのバージョンを上げれば解決するとありましたが、kerasとtensorflowのバージョンを上げたくなく対応策を模索しました。
https://stackoverflow.com/questions/78010704/cannot-import-name-ops-from-keras

エラーから原因を予想しつつ、色々と対応考えることで何とか解決できたので、参考になればと思い、記事にしました。

# 環境
エラーが出た環境は以下の通り
* Windows 11 Pro
* Docker Engine v20.10.21
* Python 3.10.12
* tensorflow 2.14.1
* keras 2.14.0
* keras_nlp 0.14.1
* autokeras 1.1.0

# エラーの原因
エラー文の全文は以下の通り。

```
  File "/xai-app/src/experiment_image_regressor_cpu.py", line 14, in <module>
    from modeling.autokeras import create_ak_image_regressor
  File "/xai-app/src/modeling/autokeras.py", line 1, in <module>
    import autokeras as ak
  File "/usr/local/lib/python3.10/dist-packages/autokeras/__init__.py", line 15, in <module>
    import keras_nlp
  File "/usr/local/lib/python3.10/dist-packages/keras_nlp/__init__.py", line 23, in <module>
    from keras_nlp.api import *  # noqa: F403
  File "/usr/local/lib/python3.10/dist-packages/keras_nlp/api/__init__.py", line 20, in <module>
    from keras_nlp.api import layers
  File "/usr/local/lib/python3.10/dist-packages/keras_nlp/api/layers/__init__.py", line 20, in <module>
    from keras_nlp.src.layers.modeling.alibi_bias import AlibiBias
  File "/usr/local/lib/python3.10/dist-packages/keras_nlp/src/__init__.py", line 23, in <module>
    from keras_nlp.src import layers
  File "/usr/local/lib/python3.10/dist-packages/keras_nlp/src/layers/__init__.py", line 15, in <module>
    from keras_nlp.src.layers.modeling.cached_multi_head_attention import (
  File "/usr/local/lib/python3.10/dist-packages/keras_nlp/src/layers/modeling/cached_multi_head_attention.py", line 16, in <module>
    from keras import ops
ImportError: cannot import name 'ops' from 'keras' (/usr/local/lib/python3.10/dist-packages/keras/__init__.py)
```

エラー文を見る限りでは、
* autokerasをimport
* autokerasからkeras_nlpをimport
* keras_nlp.apiからlayersをimport
* layersの中の`cached_multi_head_attention.py`から`from keras import ops`を実行
* import エラー

という流れ。

この時点で、`keras_nlp`と`keras`のバージョンが上手くかみ合ってないのかなと推察してました。

## なぜimportエラーが出てしまうのか
kerasはv3.0.0から`ops`というAPIを追加している模様。

https://github.com/keras-team/keras/releases/tag/v3.0.0
>New low-level keras.ops API for building cross-framework components.

つまり、kerasのv2系ではopsは存在していません。

エラーが出た環境のkerasは`2.14.0`なのでopsは存在していません。
そのため、keras_nlp　`0.14.1`はkerasの3系を前提としており、その影響でエラーがでていることがわかります。

この時点で、keras_nlpのバージョンを下げれば解決しそうだと思いました。

## 解決法
pipでkeras_nlpを`0.12.1`にダウングレードすることで無事解決しました。

```python
pip install --upgrade keras_nlp==0.12.1
```
`keras_nlp`のリリースノートを見るとv0.14.0から Keras 2のサポートが終了しています。そのため、一つ前のバージョンである`0.12.1`にダウングレードすることで解決しました。

https://github.com/keras-team/keras-nlp/releases/tag/v0.14.0
>Ditch Keras 2 support by @mattdangerw in #1658

# 終わりに
poetryでパッケージ管理しているのですが、pythonだとたまに依存関係のエラーに遭遇しますね。
本記事が皆さんのお役に立つと嬉しいです！

# 参考文献
https://github.com/keras-team/keras

https://github.com/keras-team/keras-nlp

# 機械学習関連の他記事
https://qiita.com/sasshi_i/items/a1cb8339e668f5fd4e19

https://qiita.com/sasshi_i/items/400b7672d8b80bfc3a28