はじめに
Kaggleの過去の問題ではPython2を使ったりPython3でTensorFlowを使ったりとKernelを複数使い分けることがあります。そこでJupyter上でkernel切り替えを出来るようにしようとしたら以下のようなエラーが出て数日ハマりました。
ImportError: No module named tensorflow
調べた結果、Jupyter上でのkernel切り替えが上手く機能していないのが原因のようでした。
この記事では、まずAnacondaを入れ終わった直後の状態からJupyter Notebook上でTensorFlowを使えるようになるまでをまとめます。そして最後にハマった際のエラーについて少し触れようと思います。
TensorFlowは必要ないからさっさとkernel切り替えについて教えろ
って人はJupyterのkernelを作成するからお読みください。
実行環境
- n1-standard-1(vCPU x 1、メモリ 3.75 GB)
- Ubuntu 16.04.3
- Anaconda 3.4.0
解決方法
Anacondaで仮想環境を構築する
まずはTensorFlowを入れるための仮想環境を作ります。
$ conda create -n py35_tf python=3.5
-n NAME
で名前を適当につけます。(今回はpy35_tf)
TensorFlowをインストールする
まずは作成した環境に入りましょう。
$ source activate py35_tf
TensorFlowをインストールする方法はいくつかありますが、公式ドキュメントに従ってインストールするとエラーを吐かずに済みました。
(py35_tf)$ pip install --ignore-installed --upgrade tfBinaryURL
tfBinaryURL
に自身の環境に対応するパッケージのURLをコピペします。
URL一覧はこちら。
今回の場合はLinuxのPython3.5にCPU Onlyを入れたかったので、https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.3.0-cp35-cp35m-linux_x86_64.whl
をtfBinaryURL
として挿入しました。
Jupyterのkernelを作成する
複数のフォーラムに複数の手段が紹介されており、混乱しました。
もっと効率の良い楽な方法があると思いますが、私は以下の手順で解決したのでとりあえずこちらを試してみてください。
(py35_tf)$ conda install notebook ipykernel
(py35_tf)$ ipython kernel install --user --name py35_tf --display-name Python3-TensorFlow
--name NAME
で名前を指定しないと、既存のPython3のkernelが上書きされるので要注意です。--display-name DISPLAY-NAME
でJupyter上での表記を変更できます。
以上で無事Jupyter上でのkernel切り替え、TensorFlowが利用可能になりました。
こんな感じでJupyter上でkernelを選択できるようになっているはずです。
Jupyter上で今作ったkernelを選択し、TensorFlowが使えるかのテストを行います。
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
'Hello, TensorFlow!'
が出力されればめでたしめでたし。
エラーについて
エラーが起きた手順
こちらの記事を参考にTensorFlowが入ったAnacondaの仮想環境上でkernelをインストールしました。
$ source activate py35_tf
(py35_tf)$ ipython kernel install --user --name=py35_tf --display-name=Python3-TensorFlow
しかし、いざJupyter Notebook上でTensorFlowを使用すると冒頭にも示したImportError: No module named tensorflow
というエラーが発生しました。
TensorFlowを入れたAnacondaの仮想環境(py35_tf)上ではTensorFlowを使用しても何の問題もないので、どうやらJupyter Notebook側に問題がありそうです。
エラーの原因
色々調べた結果、Anaconda上でのPythonパスとJupyter上でのPythonパスが一致していないことが原因だとわかりました。一番参考になったのがこちらのスレッド。
Anaconda上で作動しているPythonのパスを調べると
source activate py35_tf
(py35_tf)$ python
>>> import sys
>>> sys.executable
'/home/user/anaconda3/envs/py35_tf/bin/python'
となりますが、Jupyter Notebookのkernelのパスを調べると
$ jupyter kernelspec list
python3 /home/user/anaconda3/lib/python3.5/site-packages/
py35_tf /home/user/.local/share/jupyter/kernels/py35_tf
となり、py35_tfのkernelがAnaconda配下のディレクトリにないことがわかります。
次にkernelのjsonファイルを確認してみると
$ cd /home/user/.local/share/jupyter/kernels/py35_tf
$ vi kernel.json
{
"display_name": "py35_tf_keras",
"language": "python",
"argv": [
"/home/user/anaconda3/bin/python",
"-m",
"ipykernel",
"-f",
"{connection_file}"
]
}
となり、Anacondaの仮想環境py35_tf内のPythonインタープリターで確認したパス/home/user/anaconda3/envs/py35_tf/bin/python
ではないことがわかります。これはおそらく、**よくわかんないからとりあえずAnacondaの標準のPythonパスを通しておくね。作った仮想環境のPythonパスは通ってないよ。**という状態なのだと思います。
実際にJupyter Notebook上でpy35_tfのカーネルを選択し、sys.executable
でPythonパスを見てみると、/home/user/anaconda3/bin/python
が返ってきました。
じゃあjsonファイルを書き換えてAnacondaのpy35_tfと同じパス(/home/user/anaconda3/envs/py35_tf/bin/python
)を通せばいいじゃないかと思い試してみても、Jupyter上でのsys.excecutable
は変わらずでした。
エラーの原因は以上のパスの不一致だとわかったのですが、結局解決法はわからず。GCEのインスタンスを作り直してあれこれ試行錯誤した結果、本記事で紹介する方法が唯一機能してくれました。