まえがき
この記事は著者の初投稿記事になります。
分かりづらい箇所や、読み苦しい点が沢山あると思いますが、生温い目で見てください。
内容・動機
内容について
コーディング中にエラーに遭遇した時の心構えや、思考法をまとめたものです。
このエラーが出た時の対処どうすれば良い?という記事ではありませんのでご容赦下さい。
※あくまで著者個人の見解になります。
動機について
一緒にpython学習をしているコミュニティ内で個人的にpythonコードの相談やアドバイスを求められる事があり、「エラー対応時に考えている事を教えて欲しい」と言われたので、需要があるなら記事にしてみようと思った次第です。
また、エラーコード別にその対処法について書かれた記事はあっても、筆者がエラーに遭遇した時に何を考えて、解決の為にどうアクションするのかの記事は少ないと感じたので、所謂「魚の釣り方」を知りたい・参考にしたいという方に刺されば嬉しいなと思っております。
想定読者
python・プログラミング初学者向け
(プログラミング全般にまで拡げていいのか分かりませんが、大体同じだと勝手に思ってます。間違ってたらコメント下さい。)
※本記事で例として扱う画像はpython3系で出力されるエラーになります。
著者的エラーが出た時に考える・やる事
エントリーNo.1: どんなエラーか把握する
エラーが出てしまうとプログラムは回らないので、まずはこれですね。
例えば以下のエラーが出たとします。
この時点でまず著者が見る場所は
ValueError: cannot reshape array of size 15680 into shape (20,704)
の箇所です。
エラーの理由は、「配列サイズが15680だから20*704(=14080)にはreshapeできませんで!」
というものです。これはValueError以降を和訳すればすぐ分かると思います。
この様に、基本的にはエラーコードの最下部に出現する「○○Error: ~~~」の箇所に何が書かれているかを最初に理解しています。
(英語で出てきてしまうので、「英語は苦手なんじゃ、アレルギーなんじゃ〜〜ぴえん」という方は、Google翻訳なり、DeepLなりに投げてしまって問題ないと思います。)
分かりやすいエラーの場合は、この時点で解決する事が9割9分です。
しかし、こんなエラーばかり出る訳ではありませんので、もし出てきたエラーの意味が理解できない・言ってる事の意味はわかるけど、このエラー出会った事ないぞ…という時にどうするか。→エントリーNo.2に続きます。
エントリーNo.2: エラー文を丸々検索にかける
上で出てきた例の
ValueError: cannot reshape array of size 15680 into shape (20,704)
が全く意味の分からない見たこともないエラーだとして話を進めます。こういう時筆者はこのエラー文を丸々コピペして検索にかけてしまいます。
そうすると、インターネットの世界はとてもとても広いので自分より先に同じエラーと出会って解決した方が沢山います。かつ、それを丁寧にまとめて下さっているので、そう言った記事を参考にしてエラー解決を図ります。
この具体例のエラー文で検索をかけると、以下の様に出てきます。
※著者的エラー記事の選び方
多くの方がそうだとは思いますが、検索をかけて出てきたサイトを上から順番に解決するまで読んでいっています。しかし、記事を読んでもイマイチピンとこないだとか、自分の直面しているエラーとはちょっと違うなぁ…ということもあると思います。
そんな時は検索にかける文言を変えています。
この例だと、reshapeメソッドはNumpyに用意されていますので、検索クエリを
Numpy ValueError: cannot reshape array of size 15680 into shape (20,704)
なんかに変えてみると、自分が求めているエラー解決の記事が出てきたりすることが多いです。
ここまで来ると、自分のプログラムが何由来のエラーで止まってしまったのかはわかってくると思います。これを踏まえて、自分のプログラム改修を行います。→エントリーNo3に続きます。
エントリーNo.3: エラー文に戻り、どこでエラーが出ているか特定する
エントリーNo.2までに、エラーの内容はよく理解できたと思います。
ここから、どこでそのエラーが出ているのかを特定する作業に入り、これまで着目してこなかったこの部分に目を向けていきます。
----> 3 network.fit(X_train, y_train, X_val, y_val, epochs=10)
この記述と、
--> 279 self.X = X_train.reshape(batch_size, 704)
が矢印が伸びていて特徴的だと思います。
これは、「この場所でエラーが出ているよ」という事を教えてくれています。
「network.fit(〜〜〜)
を実行しようとしたけど、self.X = X_train.reshape(batch_size, 704)
って場所でエラーが出たよ」という風に読みかえる事ができるのです。
「何故ここでエラーが出たのか?」となりますが、それはエントリーNo1, No2で終わらせているので
--> 279 self.X = X_train.reshape(batch_size, 704)
の場所を、batch_size(=20) * n = 15680 となる様なnの値を求めてあげれば、エラーとしては解決する事がわかります。(n=784になるので、704→784に修正すればOKです。)
その他: 筆者がやっている事
以上のエントリーNo1〜No3が、大まかに筆者がエラーと遭遇した際に実際に考えている・実行している事になります。
それ以外にも、エラー対応をする時にやっている事を紹介したいと思います。
print文をフル活用する
エラーの場所・発生理由は分かったけど、自分がどこでミスをしているのか分からなくなる時があります。
こういう場合、エントリーNo3で注目する箇所に繋がっているプログラムの場所をひたすらprint文で出力しまくるという事をしています。(決して効率が良いとは思いませんが、確実な方法ではあると思っています。スマートなやり方があれば是非コメント下さい。)
どんなプログラムに取り組んでいるのかにもよりますが、見ている物は、
・変数の中身の値 ex):print(result)
・変数のサイズがどうなっているか ex):print(result.shape)
・入力値の変数型が想定したものになっているか ex):print(type(input))
なんかを主に気にしている様な気がします。
使っているフレームワークや、ライブラリの使い方が合っているか
基本的にプログラムは用意されているライブラリやフレームワークを使ってコーディングすることがほとんどだと思います。1から自分で作るケースはレアだと思うので、エラーが引用しているライブラリ・フレームワーク等で出ていた場合、自分が使っている道具の使い方が正しいのかどうかも良く確認します。
確認の仕方としては、エントリーNo2と一緒で、使っているライブラリ・フレームワークをそのままGoogleに投げるという事がほとんどです。
この場合、ほとんどの場合で公式が用意しているドキュメントが引っかかると思いますので、それを読みに行くと言った感じです。
(十中八九英語なので、翻訳機能をフル活用してあげてください。)
Qiitaの記事なんかで、日本語翻訳してまとめて下さっている方がいたらラッキー位の感覚でいますので、もし見つけた時は感謝して読みに行っています。
エントリーNo.4: エントリーNo.1〜No3.(+αその他)をPDCAする
最終的に、ここまで紹介した事を、エラーが見つかる度に繰り返しています。
結論
個人的なエラー対応のやり方・心構えをつらつらと書いてきましたが、これらはあくまで一例に過ぎません。今回紹介したやり方を踏まえて、皆さん自身でより良いエラー対処方法を確立していって頂けると良いのかなと思っています。
また、「エラーを見てから原因特定・修正まで何故そんなに早いのか」と聞かれる事がありますが、今回紹介した思考法に加えて過去に似た様なエラーを経験しているからというのが一番大きな要因だと思っています。
ですので、「色んなコードを読み書きして、色んなエラーに出会う事が一番良い方法」だという事をお伝えしたいと思います。
おわりに
Qiitaで初めて記事を書いてみましたが、物凄く書きやすくて驚きました。
今後も定期的に何かしらアウトプットしていきたいなと思わせてくれる良いサービスでした。