IT + X

ITと何かのコラボレーションは時代を変えるかも

変な夢をみた

今日、変な夢をみた。

なぜか自分は銀行で派遣社員として働いていたが、突然聞いたこともない海外の国に転勤を命令される。
同じように転勤を命令されてた社員が退職したが、自分も同じように退職した。
しかし、その転勤した社員は会社の仕込みで、自分を辞めさせるために演技するよう指示されたと白状する。
そんなことしなくても辞めるのにと思ったが、会社のやり口が気に入らなかったので、思い切り会社で言いたいことを言ってやめた。
その後、派手な刺青が背中にある会社のリーダーがやさしかったり、美人の女刑事と付き合うことになったりとわけがわからない展開になる。

そもそも派遣社員は契約解除でクビにできるので、こんな退職工作はしなくてもいい。
ただ、リストラを疑似体験して、改めて酷い制度だなと思った。
経済的なこともあるが、お前は役立たずだということで、長年属していたコミュニティから排除されるのは、仲間意識の強い日本人にはつらい。

株式会社という制度は、西洋で考え出されて明治に日本に導入されたが、日本の文化とは合っていない。
市場経済では、企業はお互い競争しているので、自然淘汰の法則で時代遅れの企業は市場から退場するしかない。
企業はコミュニティとしては永続的ではなく、あまりにも不安定だ。

自分も体験があるが、いつリストラされるかわからないような会社でまじめに働く気は起きない。
せいぜい会社を利用して、自分のキャリアパスだけを考えて行動するという嫌な奴になってしまう。
それよりも誰かに貢献して、自分も学んで向上できるシステムの方がいい。

企業がリストラしたり倒産したりするのは仕方がないが、そこで培われた人間関係や協力体制を保存できないのだろうか。
よく同じ会社を辞めた人たちがコミュニティを作ったりするが、そういうのがもっと広がるといいかもしれない。
また、政府や地方公共団体が今のような失業対策ではなく、最低限の生活を保障しつつ新たなコミュニティへの参加をサポートすることはできないのだろうか。

人材の流動性と言って転職がいいことだと言われる時代になったが、アメリカのやり方を盲信しているだけで、自分たちの文化や歴史を何も考えていない気がする。
さすがに終身雇用や年功序列を続けるのは無理だと思うが、流動性はありつつアメリカ型ではない人にやさしいしくみを模索すべきなのではないか。
働く形態も企業に雇用されるだけでなく、起業やコラボレーションなどいろんな形があっていいと思う。

なぜ今の企業の形がひどいかというと、公正ではないからなのだと思う。
正規雇用は、正社員という制度を維持するために一部の人を犠牲にしているしくみだし、企業のリストラも誰が生き残るかのサバイバルゲームになっている。
そうではなく、人々が協力して何かを成し遂げるためのしくみで、関わった人がみんな幸せになれるような形をめざすべき。

また、自分のことだけしか考えない風潮も、人材の流動性という名のもとに広まっている。
元々日本人は相手に気遣いできる文化を作ってきたので、その文化を生かした方がいい。
自分のことしか考えないイケイケのアメリカ人を見るたびに、品がないなと思ってしまう。

変な夢を見て、そんなことを考えた。
しかし、夢って後から考えるとおかしなところが色々ある。
人間の思考は、もともと非論理的なものなのかもしれない。

プログラミング独学をプロジェクト型学習でやってみた

f:id:anthony-g:20220205132848p:plain

静的サイトジェネレータが話題だったので、去年からGatsby.jsを学んでたのですが、
ただ単にチュートリアルやるだけではつまらないので、プロジェクト型学習でやってみることにしました。
前々から私は、プログラミングはテスト勉強的なやり方では身につかないと思っていて、
いきなりプロトタイププロジェクトで作りながら学ぶのが一番だと思ってましたが、
今回やってみて問題点も色々わかりました。

プロジェクト型学習とは

プロジェクト型学習とは、教科書を読んで練習問題を解く学校型の学習ではなく、
実際にソフトウェアを開発しながら学習していく実践型の学習方法です。
今回は、まずJavascriptの知識をアップデートして、Reactはプログラムを作りながら学ぶ戦略を取りました。

Gatsby.js学習の経緯

まずはGatsby.jsの基本的なことをサイトのドキュメントで学んで、いきなりコードを書きはじめました。
最初はローカルPCで動かして、AWS関連のコードを書き出したころに、AWS AmplifyにGitHub経由でプッシュする環境に移しました。
ただ、実際にやってみると結構タフで、自力で不具合を特定して修正するのは何回も心が折れかけました。
そんな悪戦苦闘の中での学習だったから、理解も進んだのかなと思います。
とりあえず、当初考えていた基本機能が正常に機能することを確認したので、フェーズの区切りとしました。

プロジェクト学習の良い点

まずは、プロジェクト型学習の良い点 としては、

  • コードの意味を理解することができる
    テスト勉強では、テストで点数を取ることが目的なので丸暗記になりがちですが、
    プロジェクト学習では、自分の作りたいものがはっきりしているので、
    コードがどういう意味なのかを理解しながら学ぶことができます。
    ただ、コードが入り組んでくると訳が分からなくなるので 、
    コードを機能ごとに分割して依存関係をできるだけなくすような工夫が必要でした。
    Reactは、自然とそういう設計を強制するので、いいフレームワークだと思います。

  • より実践的なスキルが身に付く
    チュートリアルにあるサンプルは、事前に動くことが確認されているのでエラーになることはありませんが、
    プロジェクトのコードは、自分で原因を突き止めてデバッグしていく必要があります。
    いきなりそれは敷居が高いと思うかもしれませんが、現実のプロジェクトでは当たり前に起こることなので、
    最初から体験しておいたほうがいいでしょう。

  • やってて楽しいので継続しやすい
    チュートリアルのサンプルを動かしても感動はありませんが、
    自分が考えたプロトタイプが動くと「動いたー!」という喜びがあります。
    そういう体験をすると、長く続けることができますし、学ぶ楽しさも感じることができます。

プロジェクト学習の悪い点

  • 行き当たりばったりな学習になりがち
    プロジェクト型学習では、教科書のように基礎から応用に網羅的にやるのではなく
    実装に必要な知識から学んでいきますので、どうしてもあちこちつまみ食いみたいな状態になります。
    プログラムを動かすためには、設定手順やどのライブラリ 使うかといった周辺の知識も必要になります。
    そのため、なかなか本題に入っていけないという場面も結構ありました。

  • 基礎ができてないので、問題特定に時間がかかる
    Gatsbyは、JavascriptとReactを知っておく必要がありますが、今回のプロジェクトではReactの知識がなかったために
    不具合の原因特定に時間がかかったことが何回かありました。
    具体的には、Javascriptの非同期処理とReactのHookについてよく分かってなかったのでなかなか不具合特定ができませんでした。
    エラーのたびに勉強すればいいかと思っていましたが、基本的なことは事前に学んでおいた方が効率はいいですね。

  • うまく動作しないことが続くとモチベーションを維持するのが難しい
    なぜうまく動かないかわからない状況が続くと、モチベーションも下がってしまいます。
    そんな時、私は違う作業をしたり、動画をみて気晴らししたりして気分を変えるようにしました。
    ただ、できるだけそういう状況にならないよう学習プランをたてたほうがベターでしょうね。

今回のケース特有の問題

あと、Gatsby.js特有の問題とAWS絡みの問題もありました。

  • JavascriptとReactを前提知識として求められる
    再度言いますが、Gatsby.jsはJavascriptとReactによって作られています。
    なので、JavascriptとReactの基礎は事前に学んでおくべきです。
    ただ、フロントエンド技術は一番変化の激しいので学びにくいジャンルでもあります。
    特に、Reactの変化は、ついていくのが大変ですね。
    また、他のIT技術も、複数の技術の基本知識が必須となっていることがありますので、
    事前に学ぶべきことを知ることは、新しい技術を学ぶ上で重要なことです。

  • 環境構築が大変
    今回、AWS上に実行環境を作りましたが、これがかなり面倒臭かったです。
    認証機能をAWS Cognitoを使ってやったので、テストもローカル環境でできなかったのが失敗でした。
    認証などAWSに依存する部分は切り離してやるべきでした。 ただ、後で機能追加する場合は、それも難しいのでちゃんとテスト環境を作るべきでしょうね。
    今回は、時間の関係でそこまでできませんでした。
    こういうのも、やってみないとわからないものですね。

このように、プロジェクト型学習は問題はありますが、プログラミングの学習方法としては正しい方向だと思います。
では、どう実行していけばいいでしょうか?

  • 前提となる基礎知識を事前に一通り学ぶ
    いきなりプロトタイプを作り出すのではなく、とりあえず基礎知識は一通り学んだ方がいいです。
    今回のケースでは、Reactの知識のアップデートをしなかったのがよくなかったです。
    ただ、暗記する必要はなく、一通り流して後でそういうのもあったな程度でいいと思います。
    別に、テストで正解する必要がないのですから、うる覚えなら後でまた調べればいいだけです。

  • 最初は、環境依存部分をできるだけ排除する
    ローカル環境で、ビルド、テストできる環境を作ります。
    データベースなど、ものによってはクラウド上で実行したほうがいいものもあるでしょうが、 極力ローカルで開発できるようにしたほうがいいと思います。

  • できればアドバイスしてくれるメンターがいるのが理想
    これはなかな難しいでしょうが、聞ける人がいたら方向修正できますし、そのほうが効率はいいでしょう。
    ただ、メンターがいる人なんてレアケースなので、独学でやる場合はネットで調べながら試行錯誤するしかないでしょう。
    ネット上の情報は英語で書かれていることが多いので、英語はいやがらずどんどん読んでいきましょう。
    今は機械翻訳のサービスがあるので簡単に日本語にできますが、IT技術の英語はちょっと頑張れば読めますので、
    この際英語も読めるようになりましょう。

結論

プロジェクト型学習は、難易度は少し高いですが、成果物ができますので、オープンソースで公開したり、 サービスで使ったりできます。
とにかく、失敗を恐れずプロジェクト型学習をどんどんやっていったほうがいいですね。

JAMStackをいまさらながら解説してみる

最近、JAMStackという考え方を、遅まきながら知りました。
静的サイトジェネレーターは昔から知っていましたが、CD/CIやBaaSなどと組み合わさってこんなに進化していたのは驚きでした。
ということで、JAMStackについて調べた内容をまとめてみました。

JAMStackとは

JAMStackとは、静的ファイル(HTML, CSS, Javascript)を基本とした新しいタイプのウェブアーキテクチャーです。
ちなみに、JAMStackのJAMとはJavascript + API + Markupの略です。

現在のメジャーなCMSは、ウェブサーバーとDBサーバーの連携により構成されています。
WordPressDrupalといったCMSが有名ですね。
なので、ユーザーがブラウザでアクセスするとウェブサーバーがDBサーバーに問い合わせてHTMLを返します。

f:id:anthony-g:20210609145504p:plain

この構成は、ダイナミックなウェブコンテンツを生成するのにはいいのですが、リクエストのたびにDBアクセスが発生するのでサーバー負荷が高くなります。

JAMStackは、データ登録時HTMLを生成しHTMLファイルなど静的ファイルのみでコンテンツを構成します。

f:id:anthony-g:20210609163810p:plain

上の図では、まず最初に記事データをGitHubなどのバージョン管理システムにプッシュします。
すると、静的サイトジェネレーターというHTMLを生成するプログラムが自動で実行されます。
生成されたHTMLファイルはCDN(コンテンツ配信システム)に配置されます。
JAMStackでは、静的ファイルのみで構成されてデータベースとの接続は行いません。
ただし、動的コンテンツが必要なこともありますので、ウェブAPIを公開するサードパーティサービスを利用します。

JAMStackのメリット

では、WEB+DB方式より優れているJAMStackの点はところはどこなのでしょうか?

  • CDNでの運用の容易さ
    JAMStackは、基本的に静的ファイルのみを扱いますので、CDNへファイルをアップロードするだけで運用が簡単です。
  • スピード
    DBアクセスがないので、ユーザーからのアクセスにも素早く返すことができます。大規模なアクセスが集中するサイトに向いていますね。
  • セキュリティ
    既存のCMSは、複雑なプログラムになってしまっているのでセキュリティの脆弱性がしょっちゅう出ます。しかし、JAMStackはその心配がありません。
  • バックアップ
    静的ファイルだけで構成されているのでバックアップも簡単です

ただ、JAMStackにも向いていない分野があります。

  • 更新頻度
    プラットフォーム系サービスなどコンテンツがしょっちゅう更新されるようなサイトだと、頻繁に静的ファイルのリビルドが走ることになるので向いていません。ただ、ヘッドレスCMSというサービスを使えば問題はありません。

  • コーディングの必要性
    後ほど説明しますが、静的サイトジェネレータというプログラムを実行することになりますので、エンジニアでないと運用できない部分が増えることになります。

JAMStackを実現する技術

JAMStackは、いくつかの要素技術によって構成されています。

  • 静的サイトジェネレーター
    JAMStackでは、最終的にHTMLやCSS, Javascriptなどの静的ファイルを生成しますが、それを行うのが静的サイトジェネレーターです。
    静的サイトジェネレーターとして有名なものは以下のようなものがあります。

Gatsby.js
www.gatsbyjs.com

Hugo
gohugo.io

Jykill
jekyllrb-ja.github.io

  • CD/CI
    プログラム開発では、CD(継続デリバリー)/ CI(継続インテグレーション)は当たり前ですが、ウェブコンテンツ制作でも必須のものとなりそうです。
    JAMStackが可能になったのは、CD/CIサービスが充実したことも理由の一つと言えるでしょう。
    有名なCD/CIサービスとしては、GitHubやBitBucketなどがあります。

  • CDN
    CDNコンテンツ配信ネットワーク)の普及もJAMStackには重要な要素です。
    CDNは、効率よくコンテンツを配信するしくみで多くの大規模ウェブサイトで利用されています。
    JAMStackは、CDNの使用が前提となる技術となっています。

  • Web API
    静的ファイルのみではダイナミックなコンテンツを提供することができません。
    データ更新毎に静的ファイルを生成するという方法もありますが、あまり現実的ではありません。
    そんな時は、APIを公開している外部サービスを利用します。
    現在では、認証や決済、CMSなどの機能を公開しているサービスがたくさんあります。

JAMStackエコシステム

https://miro.medium.com/max/700/1*TdRFV0LAG7TG3US2YJMALA.jpeg

ここにきてJAMStackが話題になったのは、様々な関連サービスによって構成されるエコシステムが実用レベルになってきたのがあります。
上の図のように、現在では様々なフレームワークやサービスが提供されています。
この中で、いくつか注目のサービスについて解説しましょう。

Netlify

www.netlify.com Netlifyは、JAM Stackという言葉を考えた会社で、提供するサービスもJAM Stackに特化したものになっています。
無料プランで色々できますので試しに使ってみてはいかがでしょうか。

Firebase

firebase.google.com Googleが提供するBaaSと呼ばれるサービスで、認証やデータ保存、Web API公開などが手軽に利用することができます。
詳しくはこちらのブログ記事で解説してますので、よかったら読んでみてください。

blog.it-plusx.com

AWS Amplify

aws.amazon.com Amazon AWSが提供するNetlifyとFirebaseが一緒になったようなサービスです。
AWSの他のサービスとシームレスに連携できるので、AWSを利用しているユーザーには便利なサービスです。

駆け足でJAM Stackについてまとめてみましたが、イメージできましたでしょうか。
まだまだWordPressなどの従来のウェブシステムが主流な状況ですが、これからはJAM Stack型のサイトが増えていくものと思われます。
ITエンジニアならぜひともキャッチアップしておきたい技術ですね。

ITエンジニアになりたい人が就職する前に学んでおくべきこと

最近、ITエンジニアになりたいという若い人のツイートをよく見ます。
私がITエンジニアなりたてのころは、未経験でも雇ってくれる会社は結構あってITエンジニアになりやすい時代でした。
しかし、PCやソフトウェアは高くて、Unixマシンは数百万以上していて個人で買えるようなものではありませんでした。
それに比べれば、今はPCは20万も出せば最高スペックのものが買えるし、開発ツールもほぼ無料で使うことができます。
また、書籍やネット上の情報もたくさんあって、自分でいくらでも学ぶことができるのでいい時代になったなと思います。

ただ私もそうでしたが、全くの初心者だと何から学べばいいかわからないので、高額なスクールに行く人が多いのでしょう。
しかし、何を学ぶべきかわかれば独学で安く学ぶことができます。
ということで、初心者の方がITエンジニアとして就職する前に学んでおくべきことをまとめてみました。

私がエンジニアになったころは、仕事をしながら勉強するしかなかったのですが
日々の業務を行いながら学ぶのはかなりきつかったです。
なので、事前に必要なことは学んでおくことをお勧めします。
ただ、プロジェクトによって必要なスキルは変わってきますので、最大公約数的なこれは学んでおくべきことだろうと思われるものを選びました。
それでも、結構な量になってしまいましたが。
とりあえずは、一般的なソフトウェア開発(ウェブ、業務システム)を行うエンジニアを想定しています。

プログラミング言語

初めて学ぶ言語は何でもいいと思います。
なぜなら、どのプログラミング言語も同じような機能であることが多いからです。
ただ、学びやすい言語を選んだほうがいいでしょう。

初心者におすすめの言語はC#です。
理由は、C#は今どきの言語が備えておくべき機能を装備していて、文法にクセがなく、プログラムロジックに集中できる言語だからです。
その上、C#の開発用IDEであるVisual Studioがよくできていて、エディタで編集している時にスペルミスなど単純なエラーは教えてくれるのでコーディング効率は高いです。

また、ウェブ開発ではJavascriptが必ず必要になりますが、最初にやる言語としてはおすすめしません。
なぜなら、言語として結構クセがあり、型のない言語なのでデバッグがしづらいという性質があります。
なので、Javascriptはプログラミングになれた頃に学ぶのがいいでしょう。

プログラミング言語は、自分で書いて動かしてみないと習得できませんので、
本で大体の書き方を理解したらどんどん自分でプログラムを書いてみましょう。

C#Javascriptのおすすめ書籍

開発ツール

プログラム開発を行う上で開発ツールを使うことは必須のスキルです。
その中でもエディタは、必ず必要になる開発ツールです。
Visual Studio CodeなどのGUIベースのエディタも人気がありますが、
エンジニアであればVimをマスターしておいたほうがいいでしょう。
なぜなら、Linuxサーバーのようにターミナルでしか作業できない環境でも、Vimは必ずインストールされています。
キーバインドも慣れるととても使いやすいので、ぜひVimをマスターしておいてください。

また、ソースコード管理のGitコマンドの使い方も、ITエンジニアならマスターしておくべきです。
さらに、今どきのソフトウェア開発ではGitHubを使うことも多いので、プルリクエストやイシュー管理なども使いこなせるようになっておきたいところです。
GitHubと合わせてJenkinsやCircle CIなどのCD/CIサービスにもなれておいたほうがいいでしょう。
CD/CIサービスとは、GitHubと連携して自動でテストやデプロイを行うためのサービスです。
CD/CIによって開発効率は格段に上がりますので、知識だけでなく使いこなせるようになっておきましょう。

エディタ、GitHubのおすすめ書籍

データベース

データベースは、あらゆるプロジェクトで必ず扱うことになる技術です。
主に、プログラムからDBに対してSQLによる問い合わせを行うことになるので、
DBの基本とSQLの書き方については熟知しておくべきでしょう。
また、DB設計は経験のあるDB専門のエンジニアが行うことが多いですが、
できればDB設計できるくらいの知識も学んでおいたほうがいいでしょう。

データベース、SQL

達人に学ぶDB設計 徹底指南書

達人に学ぶDB設計 徹底指南書

ネットワーク

現代のITシステムは、スタンドアロンで使われることは少なく、
ほとんどがネットワークに接続されていて、プロトコルとしてTCP/IPが使われています。
また、通信系のプログラムでは、パケットキャプチャーソフトなどによってどのようなやりとりが行われているか見る必要がある場合もありますので、パケットキャプチャーデータの見方も学んでほしいところです。
TCP/IPの知識も、ITエンジニアにとって必須の知識ですね。

TCP/IPのおすすめ書籍

サーバー

サーバーは、どちらかというとインフラ系エンジニアの範囲だと思われていますが、
サーバー側のプログラムを作る時は、サーバーについて知っておく必要があります。
まずは、Linuxサーバーについて学んでおいて、余裕があればWindowsサーバーにも挑戦してみましょう。

サーバーのおすすめ書籍

コンピュータアーキテクチャ

コンピュータの構造や基本となる理論についての知識が、実際の仕事で必要になることはありませんが コンピュータがどのように動いているかについての基礎知識は学んでおいたほうがいいと思います。
「コンピュータシステムの理論と実装」では、ハードウェア部分のデジタル論理回路からOSまでを網羅した内容になっていて
コンピューターの動作がイメージしやすい内容になっているのでお勧めの本です。

コンピュータアーキテクチャのおすすめ書籍

アルゴリズム

アルゴリズムも、実際のプロジェクトで必要となることは少ないですが、
これも基礎知識として学んでおいたほうがいいでしょう。
「問題解決力を鍛える!アルゴリズムとデータ構造」という本がC++で解説してますので、ついでにC++も学んじゃいましょう。

アルゴリズムのおすすめ書籍

スラスラわかるC++ 第2版

スラスラわかるC++ 第2版

セキュリティ

ITシステムを構築する上で、セキュリティはいまや最も優先度の高い問題となっています。
ウィルスやデータ改ざん、盗聴などいまやITシステムは様々な脅威にさらされています。
ITエンジニアとして、セキュリティに関する知識も必須と考えるべきでしょう。

セキュリティのおすすめ書籍

セキュリティ技術の教科書 第2版 (教科書シリーズ)

セキュリティ技術の教科書 第2版 (教科書シリーズ)

  • 作者:長嶋 仁
  • 発売日: 2020/03/18
  • メディア: 単行本(ソフトカバー)

設計方法
ソフトウェアを開発するためには、プログラミング言語を習得するだけではだめで
どういう構成にするかが重要になってきます。
今どきのプログラミング言語オブジェクト指向言語ですので、クラスやオブジェクトをどう設計するかというオブジェクト指向設計について知っておく必要があります。
また、そのオブジェクト指向設計でよく使われるパターンはデザインパターンとして整理されています。
仕様変更に強い設計を行うために、オブジェクト指向設計デザインパターンも学んでおくべきトピックです。

設計関連のおすすめ書籍

プロジェクト管理
プロジェクト管理というとプロジェクトマネージャーの仕事だと思われがちですが、
エンジニアもプロジェクト管理について知っておく必要があります。
なぜなら、大抵のプロジェクトは予算も期間もギリギリであることが多く、
途中で仕様変更を押し込まれることが多いので、理不尽な要求ははねつけるためにも理論武装が必要になります。
そして、不確定性の高いプロジェクトではアジャイル開発やスクラムといった方法論が使われることが多くなりました。
デスマーチプロジェクトに巻き込まれないためにも、プロジェクト管理についてはエンジニアも知っておくべきです。

プロジェクト管理のおすすめ書籍

英語
今や日本語のIT情報は、書籍やネットから多く得られるようになっていますが、最新の情報など英語での発信がメインとなっている情報もたくさんあります。
特に、詳細な技術情報は英語でしか得られないことが多いので、英文を読めるスキルはエンジニアには必須のスキルとなっています。
さらに、文章を書いたり会話することができるようになるのがベストですが、まずは英文を読めるように努力してみましょう。
ただ、外国語の習得はテスト勉強のように短期集中でできるものではなく、長い時間をかけてたくさんの文章に触れる必要があります。
なので、興味のあることを英文でたくさん読んでみましょう。
「Hackers」は、マイクロソフトやアップルがシリコンバレーでどのように起業されたかの歴史を解説した内容になっていて、日本語訳も昔出ていました。
ITエンジニアには興味深い内容になってますし、Kindleだと電子辞書が使えるのでわからない単語を調べながら読んでみてください。
根気強く読んでいれば、いつの間にかスラスラ読めるようになるのでがんばってください。

Hackers

結論

かなり盛りだくさんになってしまいましたが、ITエンジニアをめざすならこれくらいは学んでほしいところです。
ただ、全てを完璧に理解しようとせず、どれか一つを深くやって他はおおまかな知識だけでも頭にいれるようにすればいいと思います。
ソフトウェア開発エンジニアだと、プログラミング言語と設計あたりを中心にやったほうがいいでしょう。
そして、就職したあとに他の分野も深めていけばいいと思います。
基礎がしっかりしているエンジニアになるには時間がかかるものですが、技術が変わってもキャッチアップして息長く働けるエンジニアになれるでしょう。
ぜひ、そんなエンジニアを目指してください。

最後に、ITアカデメイアというITエンジニア向け学習動画サイトをやっています。
これからITエンジニアになりたい方向けのコンテンツを提供していますので、よかったらチェックしてみてください。

ITアカデメイア https://www.it-akademeia.jp/ www.it-akademeia.jp

Hands-On Machine Learning with Scikit-Learn Keras & TensorFlow Ed.2(イントロ)

Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems

Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems

機械学習の教科書的テキストとして評判のHands-On MLの第2版(英語版)が出たので早速買って読んでみました。 構成としては基本的に第一版と同じようですが、TensorFlowなどのライブラリバージョンアップに伴って内容がアップデートされているようです。 日本でも第一版は翻訳されていますが、翻訳がまずいのかイマイチ評判はよくないようです。

実は第一版はかなり前に読んだのですが、あまり理解できないところが多かったので第2版に改訂されたのを期にもう一度再読してみようと思います。
読んだ内容は何回かに分けてまとめていきたいと思います。

まず、本の内容は全体的にこのような構成になっています。

機械学習の基本知識

ニューラルネットディープラーニング

全体的に前半が非ニューラルネットアルゴリズムについてに書かれていて、後半はニューラルネット/ディープラーニングという構成になっています。
ちょっと読んだ感じでは、今回の改訂で変更、追記されたのは主に後半部分ではないかと思います。

サンプルプログラムはこちらのURLからダウンロードできます。
Jupyter Notebook形式になってますので、実行結果を確認しながらコードを読むことができます。
ハンズオンと本のタイトルにもあるように、実際にコードを動かすことを基本とする内容なので、ぜひとも自分のPCに実行環境を作って動かしながら読み進めてください。

では、まず初回ですので実行環境を作る説明をします。
私の実行環境はMacですが、他のプラットフォームでもそんなに違わないと思います。
まず、Pythonをインストールする必要がありますが、おすすめはAnacondaというパッケージシステムを使うことです。

www.anaconda.com

AnacondaはPythonだけでなく、いろんなライブラリを簡単にインストールできるディストリビューションです。
機械学習関連のライブラリが充実していて、アップデートもコマンドで簡単にできます。
上のURLからPython3のバージョン(2019年11月現在Pythonのバージョンは3.7)のインストールイメージをダウンロードしてください。
ダウンロードファイルは、インストールプログラムになっているので実行してインストールします。
ターミナルを開いて、Pythonがインストールされていることを確認します。

% python -V
Python 3.7.3

前にダウンロードしたサンプルファイル(handson-ml2/)内にrequirements.txtというファイルがあります。
これは、サンプルコードを動かすために必要なPythonライブラリの情報が書かれています。
requirements.txt

...
##### Core scientific packages
jupyter==1.0.0
matplotlib==3.1.1
numpy==1.17.2
pandas==0.25.1
scipy==1.3.1
....

以下のコマンドでrequirements.txtに書いてあるライブラリを一気にインストールできます。

% conda install --yes --file requirements.txt

ただ、requirements.txtはpipというコマンドの形式なのでcondaでインストールするとパッケージが見つからないと言われることがあります。
その時はpipコマンドで個別にインストールします。

% pip install [ライブラリ名]

サンプルコードはJupyterノートブックという形式になっています。
これはブラウザ上でPythonを動かせる環境で、実行結果がブラウザ上に表示されるので試すのにとてもいいです。

handson-ml2ディレクトリ内でJupyter Notebookを起動します。

%  jupyter notebook

ブラウザでhttp://localhost:8888にアクセスすると以下のページが表示されます。

f:id:anthony-g:20191126140054p:plain
Jupyter Notebook

次回からいよいよ内容について書いていきたいと思います。

(おまけ)ディープラーニングを学んで思ったこと

前のエントリーでディープラーニングについて書きましたが、学ぶ中で思ったことや考えたことが色々あったので書いておこうと思います。

ニューラルネットはソフトウェアのイノベーション

今までのソフトウェアは、人間がいちからプログラムを書かないと正しく機能しませんでした。
しかし、ニューラルネットではデータを与えることによって自ら改善していくようになったことはエポックメイキングなことだと思いました。
ある意味、いままで実現できなかった自動プログラミングが可能になったということだと思います。
これが進化すれば、プログラミングさえもコンピューター自身が行うこともいずれ可能になるでしょう。
ソフトウェア開発だけでなく、あらゆるものの製造やデザイン、研究などもできるようになるかもしれません。
もちろん、全てをコンピューターに代替するのは難しくて、物事の善悪を判断したり文化的背景を考えたりすることは難しいと思います。
ただ、コンピューターに依存する場面はこれからますます増えていきますので、すべての人がコンピューターについて正しい知識を持つ必要がある時代になっていくのではないでしょうか。

バイスの進化がイノベーションを可能にする

ディープラーニングの技術は最近出てきたように思われているかもしれませんが、元々のアイデアは40年前に考えられていたのですが(しかも日本人!)いろいろな意味で早すぎたため注目されませんでした。
それが、半導体チップの集積率が上がって実現可能な技術となったため一気に知られるようになりました。
一見華やかなイノベーションも地道な努力があったから可能になったということなのでしょうね。
昔、私がPCをはじめて買った頃はゲームしかできない高いおもちゃで役に立たないとさんざん言われましたが、ここまで来るとは想像もできなかったです。

学習が一番負荷がかかる

機械学習で一番負荷のかかるのは学習です。
大量のデータを用意するのも大変ですが、それをニューラルネットに入力して学習させるのにかなりのCPUパワーが必要です。
そこで機械学習に特化したチップやGPUなどを使って高速化する技術も出てきました。
アプリケーションによってデバイスにも技術革新が起こるという点で興味深い現象です。
そんな機械学習を学んでいると、ふと人間の学習についても考えるようになりました。
人間でも小中高大と16年もかけて学習していますが、そんなに長期間かけてるのにちゃんと学習できているのかと思いました。
テストで点数を取ることばかり気にして本当の理解ができていないのではないか、それは機械学習で言えばテストが通るようなモデルを作っているのと同じだと思います。
機械学習には過学習という問題があって、特定のデータに最適化された学習が行われると正しい判断ができないモデルになってしまうことがあります。
人間の教育もあまりにもテストを重視するために過学習状態になっている人が多いのではないでしょうか。
最近の日本のエリートの劣化を見ると、そんなことも考えてしまいました。
技術から人間のあり方が洞察できるというのもおもしろいですね。

多くの試行錯誤がいいモデルを作る

機械学習では、バッチでひとまとまりのデータを複数回与えてニューラルネットを改善していくことが基本動作になります。
なので、最初は赤ちゃんと同じで何もできない状態ですが、試行錯誤しながら学習することによってうまく処理できるようになっていきます。
ここで思ったのが、日本社会はこの対局にあるなということでした。
学校でも減点主義でミスするとバッテンをくらいますし、企業ではミスすると左遷されたり給料査定を下げられたりします。
こういうことをすると学習する機会を奪われることになります。
一般にはディープラーニングは話題になっていますが、今の日本社会では受け入れられない技術ではないかと思います。
特に、日本企業は終身雇用で長く働いている人が多いので、自分が用済みになりそうな技術を積極的に入れようとは思わないでしょう。
そういう意味で私は日本社会には絶望していますので、機械学習でビジネスするのなら海外がいいのではないかと思っています。

ブラックボックスではない

AIはブラックボックスで中身がわからないとよく言われますが、これは正しくありません。
前のエントリーでも説明したとおり、ニューラルネットのキモはニューロン間の接続の重みデータです。
これは見ることはできますが、ただの数値の羅列なので人間がその意味を理解できないだけです。
しかし、それをわかりやすく表示するツールや挙動を分析するツールなども出てきてますのでこれからだんだんと可視化されるようになるのではないかと思います。
なので、怖がるのではなくちゃんと理解して付き合うことが大事だと思います。

ちょっとエッセイ風に書いてみましたが、いかがだったでしょうか?
私はディープラーニングをインターネット以来のイノベーションだと思っています。
そして、単に技術的な進歩というだけでなく、仕事がなくなったり誤った使われ方をするなどの負の側面を考えることによって、これから人はどうあるべきなのかを考える機会にもなるのではないかと思います。
いずれにしても機械学習によってよりよい社会になってほしいなと思います。

ディープラーニングは難しくない

ディープラーニングという言葉は今では専門家だけでなく多くの人が知るようになりました。
自動運転車や顔認識などニュースや身の回りで使われるようになっているから広く知られるようになったのでしょうが、ディープラーニングがどのようにして動いているのかエンジニアでも知らない人も結構います。
今回、集中的にディープラーニングについて学んだのでそのまとめと学んでいて感じたことを書いておこうと思います。

まず、ディープラーニングを学ぼうと思った時に本屋さんで色々見てみたのですが、その多くが数学の教科書みたいなものばかりでした。
大学で発展してきた技術なので仕方ないのでしょう。
しかし、実際に学んでみて思ったのが、線形代数や確率などの数学は使う分にはそこまで数学は必要ではなく、実際のプログラムではライブラリが難しい部分をやってくれるのでがちで数学が必要なところはそんなにありません。
後、ほとんどの本が詳細なところにフォーカスしていて全体的にイメージしにくいと思いました。
著者が学者かエンジニアの人ばかりなので細かな所に気が行ってしまうのでしょうが、私のような初心者には全体をイメージできるほうが理解がしやすいなと感じました。
そんな中で比較的理解できたのが次の2冊でした。

この本はPythonを使ったディープラーニングの本ですが、極力ライブラリを使わず底辺から作っていくスタイルなのでディープラーニングのしくみを学ぶにはとてもいいと思います。
数学の記述も多少ありますが、高校レベル+線形代数の基礎くらいで読みとけるのでそんなに難しくないと思います。

PythonとKerasによるディープラーニング

PythonとKerasによるディープラーニング

この本もPythonを使っていますが、TensorFlowやKerasなどのライブラリを使っています。
前の本はゼロから作っていましたが、こちらの本ではライブラリを使うので実践で使うにはこちらのほうがいいかもしれません。

後、ネットの情報などでも色々学んでみて思ったのはディープラーニングの基本的なアイデアは単純だということでした。
ディープラーニングの元となるニューラルネットのアイデアは20年以上前からあったらしいのですが、最近ブレイクしたのはコンピュータの処理能力が上がったからでした。
なので、色々学ぶことは多いですが基本はシンプルですので理解するのはそんなに難しくないと思います。
では、ディープラーニングについて詳しく説明していきましょう。

ニューロン

ディープラーニングの元々のアイデアは生物の脳の研究が元になっています。
未だに生物の脳がどう動いているかは解明されていませんが、その基本要素である神経細胞ニューロン)はどう動いているかはわかっています。
f:id:anthony-g:20190927123555p:plain この図のようにニューロンは電気信号を伝える細胞で、複数の入力と一つの出力を持つ素子になっています。
そして、入力信号がある閾値を越えるとニューロンが発火し信号を出力します。
ディープラーニングはこのアイデアを元にコンピューター上で実現された技術です。

ニューラルネット

では、このアイデアディープラーニングではどう使われているのでしょうか?
ここでニューラルネットというものが出てきます。
ニューラルネットとは、ニューロンを複数束ねてそれぞれを信号線で接続した形のものを言います。
下図のようなものが一例です。

f:id:anthony-g:20190927124302p:plain

ニューロンを複数持つグループが層になっていてそれぞれ接続されているものをニューラルネットといいます。
図のように入力層、隠れ層、出力層と呼ばれる層で構成されていてこの順番で信号が流れます。
この隠れ層が100以上持つようなニューラルネットディープラーニングでは使われます。
当たり前ですが、この層が増えるに従ってマシンパワーが必要になります。
ディープラーニングがコンピューターの能力が上がらないと実現できなかった技術であることがこれで理解できると思います。

ディープラーニングワークフロー

ディープラーニングでは、データを読み込んで学習し、学習結果が正しいかをテストした後にAIとして使えるようになります。
ディープラーニング入門でよく使われる手書き文字認識の例で具体的に説明します。 まず、コンピューターに学習させるために教師データというものを用意します。
この例では、教師データは手書き文字画像とそれがなんの文字であるかを表すラベルがペアになっています。
その教師データをニューラルネットに大量に入力します。

f:id:anthony-g:20190927131627p:plain

この学習の処理がディープラーニングで一番負荷のかかる処理です。
学習の結果、ニューラルネットが手書き文字認識のために最適化されますので、それがちゃんと正しいかをテストします。
テストデータは学習したときと同じ形式のデータを使いますが、データ内容は別のものを用意します。
なぜなら、学習データに都合のいいニューラルネットになっていないかをチェックするためです。
ニューラルネットには過学習という問題があり、特定のデータに過度に最適化されると違うタイプのデータをうまく処理できなくなるからです。

f:id:anthony-g:20190927132458p:plain

何を処理するかにもよりますが、正解率99%以上が現実に使えるニューラルネットのようです。
そして、テストで問題なければ実際のデータで画像認識を行います。

f:id:anthony-g:20190927133107p:plain

これが一般的な機械学習処理のワークフローになります。
では、ニューラルネット上で学習処理はどう行われているのかを次に説明します。

学習とはニューラルネットの重みデータの最適化

前にニューラルネットは層で別れていてニューロン同士が接続されている構成をしていると説明しました。

f:id:anthony-g:20190927124302p:plain

この図ではニューロン同士がフルメッシュで接続されていますが、特定のニューロンの接続だけを取り出したのが次の図になります。

f:id:anthony-g:20190927133906p:plain

b, x1, x2のニューロンとyのニューロンが接続されていて、b, x1, x2から入力されたデータがyで出力されるということを表しています。
ここで大事なのがw1, w2という値で「重み」と呼ばれている値です。
これはニューロン間の接続に付随する値で、w1はx1にかけられw2はx2にかけられます。
ちなみにbはバイアスと呼ばれていてニューロンの発火のしやすさを制御します。
この例では右にある方程式の計算が行われて計算結果が0より大きければyは1、0以下ではyは0となるニューラルネットを表しています。
先程の手書き認識の例でいうとx1,x2は入力画像データです。
そして、w1, w2は学習処理のときに設定されます。
つまり、機械学習とはこの重みデータを最適な値に設定する処理のことをいいます。
これはすごくシンプルな考え方だと思いませんか?
私が最初にこのことを理解したとき、機械学習ってこういうことなのかと目からウロコでした。
つまり、重みの値を変えることによって手書き文字が読めるようになったり翻訳できるようになったりするのです。
実際は、後で説明するように特殊なニューラルネットを使ったり速度を上げるためのテクニックとかあるのですが、基本はこれです。
これを抑えておけばあとはTipsみたいなものと考えていいと思います。

あともう一つ説明しなければいけないのが活性化関数についてです。
前に、ニューロンは入力によってしきい値を越えると発火すると言いました。
したがって、どのような値で発火するか判定する関数を定義する必要があります。
それが活性化関数です。
上のニューラルネットの図のyのニューロンで重みをかけて計算した結果を活性化関数に渡しています。

f:id:anthony-g:20190927154640p:plain

上図の右の方程式は、重みによる計算結果を活性化関数に与えてニューロンが発火するかどうかを判定しています。
活性化関数としてはシグモイドとReLUが代表的ですが、グラフにあるようにある閾値を越えるとyの値が増えるのがわかると思います。
活性化関数もライブラリで用意されてますので引数を渡して呼べばいいだけです。

では、重みデータの最適化はどのように行われるのでしょうか?
最初は、重みデータは0で初期化されていたりランダムな数値が設定されていたりします。
それを、教師データを読み込んで正解と予測値を比べて差異がなくなるまで繰り返し試行錯誤を行います。

f:id:anthony-g:20190927153013p:plain

上の図で損失関数というのが正解と予測値の差を求める関数で、オプティマイザーは差の値を元にニューラルネットの重みデータを更新します。
損失関数には二乗和誤差とか交差エントロピー誤差などがあり、オプティマイザーのアルゴリズムもRMSPropやAdamといったものがありますが、扱うケースによってライブラリのパラメータで指定することができますので内部の詳細なアルゴリズムまで知らなくても使うことができます。
(もちろん、興味のある方はぜひ勉強してみてください。)

CNN(畳み込みニューラルネット

ディープラーニングが一番脚光を浴びたのは画像認識です。
動物や人の顔を見分けたり地形を検知したりいろんなところで応用されています。
画像認識でよく使わるのが畳み込みニューラルネット(Convolutional Neural Net)と呼ばれるものです。

f:id:anthony-g:20190927155613p:plain

上図に畳み込み層とプーリング層というのがあると思いますが、これは画像の特徴あるところを抽出する層です。
詳細は本を読んでいただいたほうがいいと思いますが、例えば人が猫の写真を見た場合、顔の形とか目などの特徴を抽出して判断しているらしいのですがそれと似たことをCNNでも数値処理として行っています。
後、ソフトマックスというのは複数の値を出力するための層で、例えば猫である確率と犬である確率と人である確率を出したい場合は3つの出力を持つソフトマックスということになります。
そして、いまやディープラーニングは人間の認識能力を上回るようになりました。
人間でも気づかないような特徴をコンピューターが認識できるようになったということなのでしょうね。

RNN(リカレントニューラルネット

ただ、CNNには過去のデータを覚えられないという弱点があります。
例えば、文脈で判断する必要のある文章や過去の動作情報が必要な対物検知など時系列のデータを扱うものには使えません。
そこで考えられたのがリカレントニューラルネット(Recurrent Neural Net)です。

f:id:anthony-g:20190927160611p:plain

上図左のRNNが一つのニューラルネットを表していて、自分の出力を入力に再投入します。
右図は詳細の図で、前のニューラルネットの結果を次のニューラルネットに入力することによって前のデータの反映した出力を行うことができます。

かなりざっとした説明になってしまいましたが、ディープラーニングを学ぶ上でこれだけ前知識があれば本を読む時にかなり理解しやすいと思います。
特にご紹介した2冊は私が見た中では一番わかりやすいのでぜひ読んでみてください。
また、ネタが溜まってきたらブログでまとめたいと思います。