Quantcast
Channel: 初心者タグが付けられた新着記事 - Qiita
Viewing all 21599 articles
Browse latest View live

【Rails】2つのテーブルを結合しつつ、欲しいカラムだけを抜き出してJSONで返すサンプルコード

$
0
0

はじめに

Railsで2つのテーブルを結合しつつ、欲しいカラムだけを抜き出してJSONにして返すサンプルコードです。

このコードで出来たJSONはネストされておらず、シンプルなので扱いやすいです。

環境

OS:macOS Catalina 10.15.1Ruby:2.6.5Rails:6.0.2.1

前提

  • UserモデルとPostモデルがある
  • User1に対してPostが多の関係
  • それぞれのテーブル名はusersとposts
  • 以下のように関連付け済み
user.rb
classUser<ActiveRecord::Basehas_many:postsend
post.rb
classPost<ApplicationRecordbelongs_to:userend

欲しいデータ

各テーブルのカラムは以下のように多数あり、
「不要なデータは取得したくない!」
という状況を想定し、#欲しいを付けたカラムだけを抜き出したJSONが欲しいとします。

- usersテーブル
    - id
    - name #欲しい
    - email
    - ...

- postsテーブル
    - id#欲しい
    - name #欲しい
    - description #欲しい
    - user_id #欲しい
    - date
    - ...

これは以下コードで実現可能です。

結論

posts_controller.rb
defposts_neededposts_needed=Post.joins(:user).select("
      posts.id,
      posts.name,
      description, #ここはusersテーブルと名前が被らない
      user_id, #ここはusersテーブルと名前が被らない
      users.name AS user_name #別名を付けられる
      ")renderjson: posts_neededend

【ポイント】

  • Post.joins(:user)postsテーブルとusersテーブルを結合

  • .select("カラム1, カラム2, ...")で欲しいカラムを指定

  • 元のカラム名が被る場合posts.nameusers.nameのようにテーブル名.カラム名として指定しないと、両方取り出すのは不可

  • テーブル名.カラム名 AS 任意名で出力されるカラム名を指定可能

  • テーブル名は複数形

出力

出力(JSON)
[{"id":1,"name":"投稿名1","description":"投稿詳細1","user_id":2,"user_name":"Brutus"},{"id":2,"name":"投稿名2","description":"投稿詳細2","user_id":3,"user_name":"Omae Dattanoka"},...]

ネストされたものよりシンプルで扱いやすいJSONに仕上がりました:relaxed:

おわりに

最後まで読んで頂きありがとうございました:bow_tone1:

どなたかの参考になれば幸いです:relaxed:

参考にさせて頂いたサイト(いつもありがとうございます)


【未経験エンジニア2日目(復習①)】URLの.htmlの削除

$
0
0

URLの.htmlの削除

やったこと

・URLの.htmlの削除

学んだこと

hraccessの存在

RewriteRule

 ディレクトリー内のURLを正規表現を用いて定義をすることができる

RewriteCond

 RewriteRuleの条件を絞るこむために記載される(RewriteRuleの直前に記載される) 

実際のコード

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html

参考サイト

.phpや.htmlなどの拡張子をURL表示させない方法
.htaccess でのリダイレクト(転送)設定の書き方

文字列とシンボルと双方の違いについて

$
0
0

はじめに

学習メモです。
今回扱う対象は以下となります。

  • 文字列(リテラル)
  • シンボル(リテラル)

文字列から数値へ変換

最初の文字列が整数に変換できない場合は0を返します。

"100".to_i#=> 100"1.5".to_f#=> 1.5"7/2".to_r#=> (7/2) Rationalオブジェクトに変換"1+2i".to_c#=> (1+2i) Complexオブジェクトに変換"123ab45".to_i#=> 123 aの前までが変換対象"123ab45".to_f#=> 123.0 aの前までが変換対象"2.3".to_i#=> 2 ピリオドの前までが変換対象"3.5.6".to_f#=> 3.5 2番目のピリオドの前までが変換対象"a123".to_i#=> 0

バックスラッシュ記法

指定する内容  生成される文字
\xxの文字そのもの
\n改行
\rキャリッジリターン
\f改ページ
\aベル
\eエスケープ
\s空白
\bバックスペース
\tタブ
\v垂直タブ
\nnn8進数表記 (nは0〜7)
\xnn16進数表記 (nは0〜9、a〜f)
\cx または \C-xコントロール文字 (xはASCII文字)
\M-xメタx
\M-\C-xメタコントロールx
\unnnnUnicode文字 (nは0〜9、a〜f、A〜F)
\u{nnnn}Unicode文字列 (nは0〜9、a〜f、A〜F) nnnnは16進数で1〜6桁まで指定可能。スペースかタブ区切りで複数のUnicode文字を指定可能

ちなみに、表中に書かれている「キャリッジリターン」とは、文字コード体系において、カーソルを文頭へ戻すことを表す制御文字です。(引用元:Weblio)

8進数表記と16進数表記

# "@"の文字コードは8進数で100、16進数で40p"\100"#=> @ 8進数表記p"\x40"#=> @ 16進数表記

出力メソッドの種類と違い

メソッド改行出力内容の構築メソッドバックスラッシュ記法
p引数ごとに改行inspectメソッドそのまま出力
print改行しないto_sメソッド適用した結果を出力
puts引数ごとに改行to_sメソッド適用した結果を出力

pのバックスラッシュ記法

p"\x61"#=> "a"p"\x0a"#=> "\n"

バックスラッシュ記法をシングルクォートで囲んだ場合は、シングルクォートとバックスラッシュのエスケープのみ適用され、それ以外はそのまま出力されます。

ヒアドキュメント

改行コードを含む文字列を指定するためにヒアドキュメントを利用します。
ヒアドキュメントは、「<<」に続けて文字列の終端を示す任意の識別子を指定します。

ヒアドキュメントには、終端を示す識別子の前にはスペースなどの文字を記述してはいけないというルールがあります。なので、階層が深い場合でも、終端は行頭に指定します。

以下はヒアドキュメントの例です。
終端を示す識別子にSQLを使用しており、2行目と3行目が文字列になります。

query=<<SQL
  select *
     from animal_table;
SQLquery#=> " select *\n    from animal_table;\n"

階層が深い場合のヒアドキュメントでは、開始の識別子の頭にハイフンをつけます。

deffoo<<-RESULT
    Ba
    nana
  RESULTendpfoo#=> "    Ba\n    nana\n"

ヒアドキュメントにダブルクォートで囲んだ時と同じような式展開やバックスラッシュ記法の適用を無効とする場合は、識別子をシングルクォートで囲みます。終端の識別子は囲まないよう注意しましょう。

a=1s=<<'SAMPLE'#{a}SAMPLEps#=> "  \#{a}\n"

識別子をダブルクォートで囲む事により、式展開が有効であることを明示的に示すことができます。

a=1s=<<"SAMPLE"#{a}SAMPLEps#=> "  1\n"

パーセント記法

パーセント記法を用いる事で文字列を囲む記号をプログラマが指定できます。
文字列の中でダブルクォートを使う場合などに、エスケープしなくてもよいので便利(らしい)です。
文字列を囲む記号には、数値やアルファベット以外の文字が使用可能です。

# パーセント記法の例a=%*cat*# 囲む記号に「*」を使用pa#=> "cat"# エスケープなしでダブルクォートを文字列中に使用a=%*"cat"*pa#=> "\"cat\""# パーセント記号に[]なども使えるa=%[cat]pa#=> "cat"

文字列のシングルクォートの時と同じにするには「%q」を使います。
また、ダブルクォートの際は「%Q」を使います。

a=1%q!#{a + 2}!#=> "\#{a + 2}"%Q?#{a+2}?#=> "3"

以下パーセント記法を表にまとめました。

書式  生成される値
%ダブルクォート文字列
%Qダブルクォート文字列 (%のみと同等)
%qシングルクォート文字列
%sシンボル
%W要素がダブルクォート文字列となる配列、要素の区切りは空白文字
%w要素がシングルクォート文字列となる配列、要素の区切りは空白文字
%xコマンド出力
%r正規表現

異なる文字コード間での文字列操作

Ruby2.0以降デフォルトのスクリプトエンコーディングはUTF-8となり、明示的に文字コードを指定しない限りUTF-8となります。

x="モンキー"x.encoding#=> #<Encoding:UTF-8>y=x.encode("SJIS")# "モンキー"をWindows-31Jに変換y.encoding#=> #<Encoding:Windows-31J>x+y#=> Encoding::CompatibilityError

sprintfによるフォーマット指定

桁数を揃える場合にsprintfという組み込み関数を使います。
sprintfは、第一引数にフォーマット、第二引数以降にフォーマットしたい値を指定します。

# 進数の指定sprintf("result: %#b",16)#=> "result: 0b10000"sprintf("result: %#o",16)#=> "result: 020"sprintf("result: %#x",16)#=> "result: 0x10"sprintf("result: %#X",16)#=> "result: 0X10"# 桁数の指定sprintf("result: %02d",1)#=> "result: 01"sprintf("result: %03d",1)#=> "result: 001"sprintf("result: %05.2f",1.1111)#=> "result: 01.11"

ここで重要なのはsprintf関数はStringクラスの%演算と同じ結果が得られるということです。

"result: %02d"%1#=> "result: 01""result: %03d"%1#=> "result: 001""result: %05.2f"%1.1111#=> "result: 01.11"

シンボル

# シンボルの記述例foo1=:"foo1"#=> :foo1foo2=:"#{foo1}foo2"#=> :foo1foo2foo3=:'foo3'#=> :foo3foo4=:foo4#=> :foo4

パーセント記法を使ってシンボル生成することもできます。
この場合、「%s」とすることで実現できます。(以下例)

%s?foo1?#=> :foo1%s{foo2}#=> :foo2

生成された値はSymbolクラスのインスタンスとなります。
文字列からシンボルを生成するには「to_sym」を使います。

v1="foo1"#=> "foo1"v2=v1.to_sym#=> :foo1v3=v2.to_s#=> "foo1" シンボルから文字列に変換

文字列とシンボルの違い

作成したシンボルは、文字の並びが同じであれば、同一のオブジェクトを参照しますが、文字列リテラルは文字の並びが同一でも、指定するごとに新たなStringオブジェクトが生成されます。
これを確かめるにはオブジェクトID(object_idメソッド)を使います。

文字列リテラルでは、毎回新しくオブジェクトを生成するのでオブジェクトIDが変わります。
一方、シンボルは同じオブジェクトを参照するのでオブジェクトIDは変化しません。
また、nilやtrueも、一つのオブジェクトを参照するので、シンボルと同様にオブジェクトIDは変化しません。

p"foo1".object_id#=> 70311790346380p"foo1".object_id#=> 70311790401140p:foo1.object_id#=> 1537628p:foo1.object_id#=> 1537628p:foo2.object_id#=> 1537948

Ruby 2.3以降では、「#frozen_string_literal:true」というマジックコメントを記述した場合、文字列リテラルで生成される文字列は値が変更できないようにfreezeされ、同じ内容の文字列リテラルは同一の文字列オブジェクトを返すようになります。

「equal?」メソッドは2つのオブジェクトが同一かどうか(等しいかどうかではない)を論理値で返し、サブクラスではオーバーライドしない慣習となっている(そうです)。
等価演算子「==」は、2つのオブジェクトが等しいかどうかを判定します。
これは多くのクラスでオーバーライドされています。

「==」と同様の動作をするメソッドに「eql?」メソッドがあります。
「eql?」メソッドは値の比較だけでなく、型の比較も行うため、値が等しくても型が違えばfalseを返します。
つまり、「eql?」メソッドは「==」よりも厳密に値の比較を行うと考えても良いでしょう。

# オブジェクトの同値性・同一性判定"foo1"=="foo1"#=> true"foo1".equal?"foo1"#=> false 互いにobject_idが異なるため:foo1==:foo1#=> true:foo1.equal?:foo1#=> true# eql?メソッド"foo1".eql?"foo1"#=> true1.0==1#=> true(1.0).eql?1#=> false(1.0).eql?1.0#=> true

破壊的メソッド

破壊的メソッド「!」は、自分自身の内容を変更するだけでなく、他の変数の参照先にも影響を与えるので気を付けなければなりません。

以下の例に出てくる「chop」メソッドは、最後の文字を取り除いた文字列を返すメソッドです。

# 破壊メソッドの例a="foo1"b=a# aとbは同じ文字列"foo"を参照pa.chop# "foo" aの参照先は変更されないpb#=> "foo1"pa.chop!#=> "foo" aの参照先が変更される("foo"に上書きされる)pb#=> "foo"

破壊的メソッドに「!」を付けるのは、同じメソッド名で破壊的でないメソッドもある場合に限った習慣(らしい)です。
「concat」メソッドのように破壊的であっても「!」が付いていないメソッドも存在します。

(まとめ) 文字列とシンボルの違い

変数に文字列を代入していくと、たとえ同じ値だとしてもそれぞれ異なるオブジェクトを示しています。
一方シンボルでは、変数に代入しても同じオブジェクトを示しています。

x="foo"y="foo"z="foo"# x, y, zはそれぞれ別のオブジェクトpx.object_id#=> 70311790464220py.object_id#=> 70311790482240pz.object_id#=> 70311790500280x=:fooy=:fooz=:foo# x, y, zは同一のオブジェクトpx.object_id#=> 1538908py.object_id#=> 1538908pz.object_id#=> 1538908

PHP HTMLのformから飛ばされた内容を受け取って表示する

$
0
0

目的

  • HTMLのformタグ内でのinputとtextareaでの入力を受け取って出力する方法をまとめる。

具体的な例

  • 下記にformタグの部分を抜粋したHTMLの内容を記載する。
<formmethod="post"action="sent.php"><inputtype="text"name="name"><textareaname="body"></textarea></form>
  • 下記に前述のformタグから送られてきたデータを受け取り表示するPHPの内容を記載する。
echo$_POST["name"];echo$_POST["body"];

Laravelにstylelint導入

$
0
0

前提

  • Laravelのプロジェクトにstylelintを導入する
  • プロジェクトのCSSはSCSSで書かれている → LaravelにSCSSを導入する方法はこちらの記事を参考にしてください。
    LaravelにSCSSを導入する方法

stylelintでできること

コードの一貫性を保ち、エラーを減らすことが可能になる


構文エラーチェックの例だと

.sample {
  background-color: #fffffff;
  disply: block;
}

無効な16進数のカラーコードとdisplayのスペルミスがあります。stylelintのcolor-no-invalid-hexルールとproperty-no-unknownルールでエラーを発見することができます。

その他にもスタイルの重複を避けることができたり、書き方を統一できたり、stylelintを導入すると様々なメリットがあります。

stylelintのルールについて

stylelintの導入

一番簡単な方法は、プロジェクトのルートディレクトリに.stylelintrcファイルを作ることです。
作成した.stylelintrcにルールを設定していきます。

例)

{"rules":{"color-named":"never","declaration-no-important":true,"function-url-quotes":"never","number-leading-zero":"never","property-no-vendor-prefix":true,"selector-max-type":0,"selector-no-qualifying-type":true,"string-quotes":"single"}}

git commit時にstylelintのルールを適用する

ルートディレクトリのpackage.jsonにコードを追加していく。

package.json
{"scripts":{"stylelint":"node ./node_modules/stylelint/bin/stylelint.js  resources/assets/sass/*.scss",},"husky":{"hooks":{"pre-commit":"lint-staged"}},"lint-staged":{"resources/assets/sass/*.scss":["npm run stylelint","git add"]}}

huskylint-stagedのパッケージをインストールするのを忘れないでくださいね^^

参考記事

チームで美しくメンテナブルなCSSを書くための 「Stylelint」導入のすすめ

列名の重複で困ったらRenameColumnsで解決

$
0
0

はじめに

今回はとても短い投稿です。
リストやCollectionを使って、自分自身を参照したFilter, LookUpを行う場合(自己結合的な)や、似たような構造のリスト、コレクション同士をFilter、結合する場合には、どうしても列名の重複が気になります。

例えば、何らかのスタッフリストのようなものがあったとします。
そのスタッフリストにはスタッフのID、名前、上司のIDが含まれています。
この時スタッフリストを自己参照して、上司の名前を解決した表を作りたいとしましょう。
単純に考えれば、「リストに列を追加して、その条件として、リストのIDがManagerIDと一致した行をとる」とすればよいです。(下図)
image.png

しかし、結果としてはManagerのTitleは解決できず、エラーになってしまいます。

それもそのはず。赤く囲んだ部分だけみれば、「自分のIDと上司のIDが一致した行」になっているからです。
本来はLookUpの外側のCol1にあるManagerIDと、LookUp内のCol1のIDが一致した行をとらなければなりません。

解決方法

解決方法は単純です。いずれかの列名をRenameColumns関数で変更してあげましょう。(RenameColumnsにかんしてはこちら)
この場合でいえば、LookUp内のCol1の列名をID,ManagerIDとも変えれば解決します。

image.png
変更後の名前は何でもよいのですが、rをつけました。これによって、LookUp関数内の、ManagerIDはLookUp関数の外側から与えられる列の値。そしてrIDはLookUp関数内の元ID という風に一意性を持たせることができました。

おわり

RenameColumnsは自己結合や外積のような場合にとても有効です。また、参照する・されるリスト間で同じ名前の列がある場合にも、列名の一意性を担保してあげるという観点から重要になります。
ぜひ簡単な例で試してみてください。

初めてのLTで意識したこと、やってよかったこと

$
0
0

はじめに

意識したこと

この発表によって聴衆に何のメリットがあるのか?を大事にした

  • 自分の話なんか興味もってもらえるかな…と不安になってしまうタイプなので、その不安の払拭のために聴衆へのメリットを持たせました
  • 今回は『飽き性でも習慣化と見える化をすれば目標達成ができる』という結果&提案を聴衆へのメリットとしました

話の流れを意識してスライドを作成した

  • 起承転結のうち、承を多めにする
    • 起:私の弱点は飽き性
    • 転:2020年の目標がある
    • 承:その目標は今までも目標としてあったけど、達成できてない
    • 転:そんな飽き性の私でも2019年に達成できた目標がある
    • 承:それらの目標を達成できた理由を具体的
    • 承:それらの目標を達成できた理由を抽象化する
    • 結:抽象化から、2020年の具体的な行動を明示する
  • 具体と抽象は意識したわけではないですが、結果としてこの流れにしてよかったと思います

タイトルスライドで笑いをとれるようにしておいた

  • 最初で笑いをとれば気が楽になる作戦を参考にして、タイトルスライドで笑いをとれるようにしておきました
  • 名称未設定.001.jpeg名称未設定.002.jpeg
    • 『始末する』という過激発言からの、『自分を始末しちゃいかんよね』は準備した発言です(笑ってくれた人たちありがとう!)

やってよかったこと

適度な飲酒

  • 申込も発表も酒の勢いでした
    • 酒の勢いと友人のお誘いがなければLTをやるのはもっと先のことになってたと思います

聴衆への声かけ

  • 飽き性のみんなー!一緒にやろ💕なスライドで、アドリブで飽き性の人🙋!ってやったら、結構手を上げてくれた人がいたの、聞いてもらえてる感があって心強かったです(手をあげてくれた人ありがとう!)
    • 当該スライド: 名称未設定.011.jpeg

結果としてよかったこと

話す内容が気負いすぎなくて良い内容だった

  • 新年の目標発表だったので、技術的な間違いとか技術レベルとか気にしなくて良いのは気楽でよかった

LT発表者が集まる卓に座った&友人が一緒だった

  • 始まる前に緊張するね〜〜!って言いあえるのは緊張緩和になりました
  • 一緒に参加した友人もはじめてだったので、はじめて同士で心強かったです

反省点

スライドがちょっと多かった

  • 5分に対して11スライドもあると、自分が心配になってしまうのでよくなかった
  • 結果何分だったのかは知らないですが、スマホで時間カウントしておけばよかったかなと思います

おわりに

  • やる前はかなり不安でしたが、終わってみると達成感あります✨
  • LTスライドの作成は全力でわかりやすさと向き合える良い機会になったと思います

謝辞

  • 場を提供してくださったTECH PLAY女子部運営のみなさま、イベントの存在を教えてくれた&LTやろうよ!と言ってくれたまいあめあさん、おかげで人生初LTを体験することができました!ありがとうございます!
  • スライドの添削をして『メッセージ性が足りない』と指摘してくれた友人Y、おかげでちゃんと聴衆を意識したスライド作りと発表ができました。飽き性の人🙋!のスライドは、友人Yの指摘無くしては生まれませんでした。いつもありがとう!
  • 発表慣れへの一歩を歩ませてくれたO教授、スライド作りの極意を徹底的に教えてくれたI教授、おかげで上手く乗り越えられました。お二人の教えは今も大活躍しています。本当にありがとうございます。
  • 7さんの発表の文章作成3つの準備が、この記事を書いたきっかけです!素敵な発表ありがとうございます!
  • そして何よりも、聴いて反応してくださったイベント参加者の皆さん!ありがとうございます!

深層学習 Day4 強化学習・Tensor Flow

$
0
0

sutudy-ai


<科目> 深層学習 

目次
深層学習: Day1 NN
深層学習: Day2 CNN
深層学習: Day3 RNN
深層学習: Day4 強化学習・Tensor Flow

深層学習: Day4 強化学習・Tensor Flow (講義の要約)

  • Tensor FlowはGoogleが提供。レイブラリとしての利用では最も多い。そのため講義ではTensor Flow中心にで学んでゆく。

Section1) TensorFlowの実装演習

線形回帰(DN65)

  • データ個数 300個
    d=3x+2(ノイズ0.3)
  • 誤差関数 平均2乗誤差
  • Optimizer 勾配降下法
  • 学習率0.1

[try]

noiseの値を変更しよう
dの数値を変更しよう

スクリーンショット 2020-01-04 12.11.10.png

$\Rightarrow$【考察】

Optimizer nameDescription
GradientDescentOptimizer勾配降下法によるオプティマイザー
AdagradOptimizerAdaGrad法によるオプティマイザー
MomentumOptimizerモメンタム法によるオプティマイザー
AdamOptimizeAdam法
FtrlOptimizerFollow the Regularized Leader アルゴリズム(これは習ってないですね)
RMSPropOptimizer学習率の調整を自動化したアルゴリズム

(参考)tensorflowのOptimizer

非線形回帰(DN66)

  • データ個数 100個
    $d = - 0.4 x^3 + 1.6x^2 - 2.8x + 1$(ノイズ0.05)
    この時、W(重み)は、-0.4,1,6,-2,8,1(xの0乗)の4つでb(バイアス)は使っていないことに注意。
  • 誤差関数 平均2乗誤差
  • Optimizer 勾配降下法
  • 学習率0.01

[try]
noiseの値を変更しよう
dの数値を変更しよう

スクリーンショット 2020-01-04 12.43.50.png

  • W = tf.Variable(tf.random_normal([4, 1], stddev=0.01)) stddev=0.01は、標準偏差0.01のランダムな初期値として、tf.random_normalで定義。

演習問題(DN67)

[try]
+ 次の式をモデルとして回帰を行おう

$d = 30x^2 +0.5x + 0.2$(ノイズ0.05)
+ 誤差が収束するようiters_numやlearning_rateを調整しよう

スクリーンショット 2020-01-04 14.36.20.png
$\Rightarrow$【考察】
iters_num(イテレーションナンバー:反復学習回数)を調整するよりも、learning_rate(学習率)を調整した方が効果が高いという結果になった。
【変更ソース】

python
importnumpyasnpimporttensorflowastfimportmatplotlib.pyplotasplt# イテレーションの変更はこちらで行う
iters_num=10000plot_interval=100# データを生成
n=100#random.rand(): 0.0以上、1.0未満で乱数生成
x=np.random.rand(n).astype(np.float32)*4-2d=30*x**2+0.5*x+0.2#  ノイズを加える
noise=0.05d=d+noise*np.random.randn(n)# モデル
# bを使っていないことに注意.
# 追加 Wの数が4から3になっているので変更
#xt = tf.placeholder(tf.float32, [None, 4])
xt=tf.placeholder(tf.float32,[None,3])dt=tf.placeholder(tf.float32,[None,1])# 追加 Wの数が4から3になっているので変更
#W = tf.Variable(tf.random_normal([4, 1], stddev=0.01))
W=tf.Variable(tf.random_normal([3,1],stddev=0.01))y=tf.matmul(xt,W)# 誤差関数 平均2乗誤差
loss=tf.reduce_mean(tf.square(y-dt))# 学習率の変更はこちらで行う
optimizer=tf.train.AdamOptimizer(0.001)train=optimizer.minimize(loss)# 初期化
init=tf.global_variables_initializer()sess=tf.Session()sess.run(init)# 作成したデータをトレーニングデータとして準備
d_train=d.reshape(-1,1)#x_train = np.zeros([n, 4])
x_train=np.zeros([n,3])foriinrange(n):# 追加 Wの数が4から3になっているので変更
#    for j in range(4):
forjinrange(3):x_train[i,j]=x[i]**j#  トレーニング
foriinrange(iters_num):if(i+1)%plot_interval==0:loss_val=sess.run(loss,feed_dict={xt:x_train,dt:d_train})W_val=sess.run(W)print('Generation: '+str(i+1)+'. 誤差 = '+str(loss_val))sess.run(train,feed_dict={xt:x_train,dt:d_train})print(W_val[::-1])# 予測関数
defpredict(x):result=0.# 追加 Wの数が4から3になっているので変更
#   for i in range(0,4):
foriinrange(0,3):result+=W_val[i,0]*x**ireturnresultfig=plt.figure()subplot=fig.add_subplot(1,1,1)plt.scatter(x,d)linex=np.linspace(-2,2,100)liney=predict(linex)subplot.plot(linex,liney)plt.show()

MNIST1(DN68)

  • MNISTとは、手書き文字のデータセットで、28✖️28✖️白黒もの11チャンネルの画像が入っている。
  • 0から9のどの数字かを予測するようなものになっている。
分類3層 (mnist)(DN69)

[try]
隠れ層のサイズを変更してみよう
optimizerを変更しよう
$\Rightarrow$【考察】
スクリーンショット 2020-01-04 19.33.05.png
隠れ層のサイズを半分にしたところ正答率が大幅に下がった。一方、optimizerをAdamからMomentumに変更したところ正答率は90から94パーセントまで上がった。他にも実施したが、RMSPropが96パーセントと最も良かった。
隠れ層のサイズを倍にもしてみたが、正答率の向上は1パーセント程度だったことから、隠れ層のサイズが十分深かったら、その後はoptimizerで調整する事が望ましいと感じた。

分類CNN (mnist)(DN70)

conv - relu - pool - conv - relu - pool -
affin - relu - dropout - affin - softmax
[try]

ドロップアウト率を0に変更しよう
$\Rightarrow$【考察】
(変更前)dropout_rate = 0.5
スクリーンショット 2020-01-04 19.54.24.png

(変更後)dropout_rate = 0
スクリーンショット 2020-01-04 20.02.13.png
もっと下がるかと思ったが、あまり変わらなかった。

例題解説

スクリーンショット 2020-01-04 20.37.06.png

$\Rightarrow$【考察】
回答は(a)
1.googlenetはInceptionモジュールの積み重ねで構成されたネットワークである。
2.Inceptinモジュール
 上記表で示しているように小さいネットワークを一つのモジュールに定義する。よって(D)は正解です。
 Inceptinモジュールは通常は、フィルターサイズを定義してあげてConvolutionで行う部分を複数のフィルターサイズを使う事でConvolutionで行う特徴となっている。
1×1の畳み込みによって次元削減を行うCは正解になります。複数の畳み込みによってパラメーター数を減らしながら表現力を改善してゆくBも正解。

回答は(a)が誤り
まずlossについては、途中のネットワークから分岐させた部分でクラス分類を行っている事がこのlossの特徴になります。

あとの例題解説は省略。

【DN73】例題解説中の確認テスト
VGG・GoogleNet・ResNetの特徴をそれぞれ簡潔に述べよ。

VGGについては、最も古く2014年のモデルになります。特徴としては、Convolution,Convolution,max_poolというような単純なネットワークの積み重ねでシンプルなものとなっている。一方他の二つと比べパラメーター数が多いのが特徴。
GoogleNetはinceptionモジュールを使っているのがと特徴。1✖️1サイズを使った次元削減や様々なフィルターサイズを使うことによるスパースなものというのが特徴的になっている。
ResNetについては<スキップコネクションアイデンティティモジュールを使うことによって残渣接続を行い、それによって深い学習が行えるという事が特徴になっている。

Keras2 (DN69)
単純パーセプトロン

OR回路
[try]
np.random.seed(0)をnp.random.seed(1)に変更
エポック数を100に変更
AND回路, XOR回路に変更
OR回路にしてバッチサイズを10に変更
エポック数を300に変更しよう
⇒ 【考察】
(変更前)np.random.seed(0)
スクリーンショット 2020-01-04 22.40.41.png
(変更後)np.random.seed(1)に変更
スクリーンショット 2020-01-04 22.49.46.png
(変更後)エポック30回→100回に変更
スクリーンショット 2020-01-04 22.58.35.png
(変更後)AND回路に変更
OR, ANDは線形分離可能だが, XORは線形分離不可能なので学習できない
(変更後)OR回路にしてバッチサイズを10に変更
スクリーンショット 2020-01-04 23.22.23.png
(変更後)エポック数を300に変更しよう
スクリーンショット 2020-01-04 23.24.53.png

分類 (iris)

[try]

  • 中間層の活性関数をsigmoidに変更しよう
  • SGDをimportしoptimizerをSGD(lr=0.1)に変更しよう

(変更前・ReLU)
スクリーンショット 2020-01-04 23.38.52.png
(活性化関数をSygmoidに変更)
スクリーンショット 2020-01-05 0.40.44.png
やはりグラフからはReRUの方が精度が良いと言える。
(最適化をoptimizer=SGD(lr=0.1)に変更)
スクリーンショット 2020-01-05 0.53.14.png

optimizer=SGD(lr=0.1)にして、時折1.0が出るように精度が上がってきた部分もあるが、ばらつきも多くなったように見受けられる。

分類 (mnist)

[try]

  • load_mnistのone_hot_labelをFalseに変更しよう (error)
  • 誤差関数をsparse_categorical_crossentropyに変更しよう
  • Adamの引数の値を変更しよう

(変更前)
スクリーンショット 2020-01-05 1.17.45.png
(変更後)one_hot_labelをFalseに変更
スクリーンショット 2020-01-05 4.51.25.png

(変更後)誤差関数をsparse_categorical_crossentropy変更
     且つone_hot_labelをFalseに変更
スクリーンショット 2020-01-05 5.04.45.png

categorical_crossentropy→ one_hot_label をTrue
sparse_categorical_crossentropy→ one_hot_label をFales
にしなければならない。しない場合エラーとなる。

(変更後)Adamのlr引数の値を変更しよう(学習率0.01 -> 0.1)
スクリーンショット 2020-01-05 5.10.06.png

RNN

(二進数足算の予測)
Keras RNNのドキュメント

  • RNNの出力ノード数を128に変更
  • RNNの出力活性化関数を sigmoid に変更
  • RNNの出力活性化関数を tanh に変更
  • 最適化方法をadamに変更
  • RNNの入力 Dropout を0.5に設定
  • RNNの再帰 Dropout を0.3に設定
  • RNNのunrollをTrueに設定

try
スクリーンショット 2020-01-07 15.54.14.png
(変更後)出力ノード数を128に変更
SimpleRNN のunits=16 $\Rightarrow$ units=128に変更。
スクリーンショット 2020-01-07 16.07.28.png
EPOCH1の段階からAcc0.9299まで上がっている。
(変更後)出力活性化関数を ReLU$\Rightarrow$ sigmoid に変更
スクリーンショット 2020-01-07 16.21.14.png
SygmoidはLeRUほどAccが上がらない結果になりました。
(変更後)出力活性化関数を tanh に変更
スクリーンショット 2020-01-07 16.33.54.png
Accが100%まであがるのにEpoch3までかかっている。

(変更後)最適化方法をadamに変更
ソース変更

pyton
#model.compile(loss='mean_squared_error', optimizer=SGD(lr=0.1), metrics=['accuracy'])
model.compile(loss='mse',optimizer='adam',metrics=['accuracy'])

スクリーンショット 2020-01-07 17.09.49.png
Accがほぼ良い結果である。

(変更後)入力 Dropout を0.5に設定
スクリーンショット 2020-01-07 16.41.19.png
Accが思うほど上がらない結果。

(変更後)再帰 Dropout を0.3に設定
スクリーンショット 2020-01-07 16.53.33.png
こちらもAcc98%どまりとなっている。

(変更後)unrollをTrueに設定
スクリーンショット 2020-01-07 17.15.36.png
こちらも良い結果である。

Section2) 強化学習

2-1強化学習とは

 長期的に報酬を最大化できるように環境のなかで行動を選択できるエージェントを作ることを目標とする機械学習の一分野
$\Rightarrow$行動の結果として与えられる利益(報酬)をもとに、行動を決定する原理を改善していく仕組みです。

【D81】強化学習1 確認テスト
強化学習に応用できそうな事例を考え、環境エージェント・行動・報酬を具大的に挙げよ。

⇒【考察】
株の投資のロボット
  環境⇒株式市場
  エージェント⇒投資家
  行動 ⇒儲かりそうな株を選んで投資する投資する
  報酬 ⇒ 株式に売買による利益・損失

2-2強化学習の応用例

マーケティングの場合
環境 :会社の販売促進部
エージェント:プロフィールと購入履歴に基づいて、キャンペーンメールを
送る顧客を決めるソフトウェアである。
行動 :顧客ごとに送信、非送信のふたつの行動を選ぶことになる。
報酬 :キャンペーンのコストという負の報酬とキャンペーンで生み
出されると推測される売上という正の報酬を受ける

2-3探索と利用のトレードオフ

環境について事前に完璧な知識があれば、最適な行動を予測し決定することは可能。

⇒どのような顧客にキャンペーンメールを送信すると、どのような行動を行うのかが既知である状況。

⇒強化学習の場合、上記仮定は成り立たないとする。不完全な知識を元に行動しながら、データを収集。最適な行動を見つけていく。

過去のデータで、ベストとされる行動のみを常に取り続ければ他にもっとベストな行動を見つけることはできない。
⇒探索が足りない状態
(上と下はトレードオフの関係性)
未知の行動のみを常に取り続ければ、過去の経験が活かせない。利用が足りない状態トレードオフの関係性
⇒未知の高度のみを

2-4強化学習のイメージ

Day4.jpg

2-5強化学習の差分

強化学習と通常の教師あり、教師なし学習との違い

結論:目標が違う

  • 教師なし、あり学習では、データに含まれるパターンを見つけ出すおよびそのデータから予測することが目標
  • 強化学習では、優れた方策を見つけることが目標

強化学習の歴史
強化学習について
・冬の時代があったが、計算速度の進展により大規模な状態をもつ場合の、強化学習を可能としつつある。
・関数近似法と、Q学習を組み合わせる手法の登場

Q学習
・行動価値関数を、行動する毎に更新することにより学習を進める方法
関数近似法
・価値関数や方策関数を関数近似する手法のこと

2-6行動価値関数

行動価値関数とは

  • 価値を表す関数としては、状態価値関数と行動価値関数の2種類がある
  • ある状態の価値に注目する場合は、状態価値関数状態と価値を組み合わせた価値に注目する場合は、行動価値関数

2-7方策関数

方策関数とは方策ベースの強化学習手法において、ある状態でどのような行動を採るのかの確率を与える関数のことです。

2-8方策勾配法

方策反復法
方策をモデル化して最適化する手法
⇒方策勾配法

\theta^{(t+1)}=\theta^{(t)}\epsilon\nabla j(\theta)

jとは⇒方策の良さ・・・定義しなければならない

定義方法
・平均報酬
・割引報酬和
上記の定義に対応して、行動価値関数:Q(s,a)の定義を行い。
方策勾配定理が成り立つ。

\nabla _{\theta} j(\theta)=E_{\pi_\theta} [\nabla_{\theta} log\pi_\theta(a|s)Q^\pi(s,a))]

科目>深層学習: Day3 RNN

$
0
0

sutudy-ai


<科目> 深層学習 

目次
深層学習: Day1 NN
深層学習: Day2 CNN
深層学習: Day3 RNN
深層学習: Day4 強化学習・Tensor Flow

深層学習: Day3 CNN (講義の要約)

深層学習全体像の復習–学習概念

スクリーンショット 2020-01-02 14.09.10.png

最新のCNN

•AlexNet
AlexNetとは2012年に開かれた画像認識コンペティション2位に大差をつけて優勝したモデルである。AlexNetの登場で、ディープラーニングが大きく注目を集めた。
モデルの構造
5層の畳み込み層およびプーリング層など、それに続く3層の全結合層から構成される
スクリーンショット 2020-01-02 14.50.59.png

再帰型ニューラルネットワークについて

Section1)再帰型ニューラルネットワークの概念

  • 1-1RNN全体像

    • 1-1-1RNNとは
    • RNNとは?$\Rightarrow$時系列データに対応可能な、ニューラルネットワークである
    • 1-1-2時系列データ
    • 時系列データとは?$\Rightarrow$時間的順序を追って一定間隔ごとに観察され,しかも相互に統計的依存関係が認められるようなデータの系列
    • 具体的な時系列データとは?$\Rightarrow$音声データ・テキストデータ...etc
    • 1-1-3RNNについて
    • RNNの特徴とは?$\Rightarrow$時系列モデルを扱うには、初期の状態と過去の時間t-1の状態を保持し、そこから次の時間でのtを再帰的に求める再帰構造が必要になる。
    • スクリーンショット 2020-01-03 6.49.42.png

      • RNNの全体像
      • スクリーンショット 2020-01-03 6.53.48.png
      • 数式
      • スクリーンショット 2020-01-03 6.57.19.png
      • コード
python
u[:,t+1]=np.dot(X,W_in)+np.dot(z[:,t].reshape(1,-1),W)z[:,t+1]=functions.sigmoid(u[:,t+1])np.dot(z[:,t+1].reshape(1,-1),W_out)y[:,t]=functions.sigmoid(np.dot(z[:,t+1].reshape(1,-1),W_out))np.dot(z[:,t+1].reshape(1,-1),W_out)
  • 1-2BPTT

    • 1-2-1BPTTとは誤差逆伝播法の復習
    • スクリーンショット 2020-01-03 13.19.44.png
    • 1-2-2BPTTの数学的記述
    • スクリーンショット 2020-01-03 12.25.31.png
    • 上からコードに紐付けると
      • np.dot(X.T,delta[:,t].reshape(1,-1))
      • np.dot(z[:,t+1].reshape(-1,1),delta_out[:,t].reshape(-1,1))
      • 3)np.dot(z[:,t].reshape(-1,1), delta[:,t].reshape(1,-1))
      • (bとcは)simple RNNコードでは簡略化のため省略
      • (bとcは)simple RNNコードでは簡略化のため省略
    • $u^t=W_{(in)}x^t+Wz^{t-1}+b$
      (コード) u[:,t+1] = np.dot(X, W_in) + np.dot(z[:,t].reshape(1, -1), W)
    • $z^t=f(W_{(in)}x^t+Wz^{t-1}+b)$
      (コード) z[:,t+1] = functions.sigmoid(u[:,t+1])
    • $v^t=W_{(out)}z^t+c$
      +(コード) y[:,t] = functions.sigmoid(np.dot(z[:,t+1].reshape(1, -1), W_out))
    • スクリーンショット 2020-01-03 13.26.22.png
    • パラメータの更新式
    • スクリーンショット 2020-01-03 13.28.08.png
    • スクリーンショット 2020-01-03 13.29.28.png
    • 1-2-3BPTTの全体図
    • スクリーンショット 2020-01-03 13.31.35.png
    • アンダーライン部$\Longrightarrow$スクリーンショット 2020-01-03 13.33.36.png

Section2) LSTM

全体像(前回の流れと課題全体像のビジョン)

LTSM全体図

スクリーンショット 2020-01-03 15.25.30.png

  • 2-1CEC
  • 勾配消失および勾配爆発の解決方法として、勾配が、1であれば解決できる。
    課題入力データについて、時間依存度に関係なく重みが一律である。$\Rightarrow$ニューラルネットワークの学習特性が無いということ。
    入力層→隠れ層への重み入力重み衝突。隠れ層→出力層への重み出力重み衝突。

  • 2-2入力ゲートと出力ゲート

    • 入力・出力ゲートの役割とは?$\Rightarrow$入力・出力ゲートを追加することで、それぞれのゲートへの入力値の重みを、重み行列W,Uで可変可能とする。$\Rightarrow$CECの課題を解決。
  • 2-3忘却ゲート

    • LSTMブロックの課題から忘却ゲートが誕生
    • 課題過去の情報が要らなくなった場合、削除することはできず、保管され続ける。LSTMの現状CECは、過去の情報が全て保管されている。解決策過去の情報が要らなくなった場合、そのタイミングで情報を忘却する機能が必要。$\Rightarrow$忘却ゲートの誕生
  • 2-4覗き穴結合

  • スクリーンショット 2020-01-03 16.24.18.png
    CECの保存の過去の情報を、任意のタイミングで他のノードに伝播させたり、あるいは任意のタイミングで忘却させたいニーズに対応するために誕生した仕組み。CEC自身の値は、ゲート制御に影響を与えていない。覗き穴結合とは?$\Rightarrow$CEC自身の値に、重み行列を介して伝播可能にした構造。

Section3) GRU

GRU全体図

  • スクリーンショット 2020-01-03 16.37.48.png

  • (背景)LSTMでは、パラメータ数が多く、計算負荷が高くなる問題があった。$\Rightarrow$GRU誕生

  • GRUとは?$\Rightarrow$従来のLSTMでは、パラメータが多数存在していたため、計算負荷が大きかった。しかし、GRUでは、そのパラメータを大幅に削減し、精度は同等またはそれ以上が望める様になった構造。

  • メリット$\Rightarrow$計算負荷が低い。

Section4)双方向RNN

  • 過去の情報だけでなく、未来の情報を加味することで、精度を向上させるためのモデル
  • 実用例文章の推敲や、機械翻訳等
  • スクリーンショット 2020-01-03 20.25.47.png

RNNでの自然言語処理

Section5)Seq2Seq

Seq2Seq全体像

スクリーンショット 2020-01-03 21.38.30.png
Seq2seqの具体的な用途とは?$\Rightarrow$機械対話や、機械翻訳などに使用されている。
Seq2seqとは?$\Rightarrow$Encoder-Decoderモデルの一種を指します。

  • 5-1Encoder RNN

    • ユーザーがインプットしたテキストデータを、単語等のトークンに区切って渡す構造
    • Taking :文章を単語等のトークン毎に分割し、トークンごとのIDに分割する。
      Embedding :IDから、そのトークンを表す分散表現ベクトルに変換。
      Encoder RNN:ベクトルを順番にRNNに入力していく。
    • Encoder RNN処理手順
      • vec1をRNNに入力し、hidden stateを出力。このhiddenstateと次の入力vec2をまたRNNに入力してきたhidden stateを出力という流れを繰り返す。
      • 最後のvecを入れたときのhiddenstateをfinalstateとしてとっておく。このfinalstateがthoughtvectorと呼ばれ、入力した文の意味を表すベクトルとなる
    • スクリーンショット 2020-01-03 21.41.40.png
  • 5-2Decoder RNN

    • システムがアウトプットデータを、単語等のトークンごとに生成する構造。
    • Decoder RNNの処理
      • 1)Decoder RNN: Encoder RNN のfinal state (thought vector) から、各token の生成確率を出力していきますfinal state をDecoder RNN のinitial state ととして設定し、Embedding を入力。
      • 2)Sampling:生成確率にもとづいてtoken をランダムに選びます。
      • 3)Embedding:2で選ばれたtoken をEmbedding してDecoder RNN への次の入力とします。
      • 4)Detokenize:1 -3 を繰り返し、2で得られたtoken を文字列に直します。
    • スクリーンショット 2020-01-03 21.52.08.png
  • 5-3HRED

    • Seq2seqの課題 一問一答しかできない。問に対して文脈も何もなく、ただ応答が行われる続ける。これを解決するためにHREDが誕生。
    • HREDとは?過去n-1 個の発話から次の発話を生成する。システム:インコかわいいよね。ユーザー:うんシステム:インコかわいいのわかる。Seq2seqでは、会話の文脈無視で、応答がなされたが、HREDでは、前の単語の流れに即して応答されるため、より人間らしい文章が生成される。
  • 5-4VHRED

    • VHREDとは?$\Rightarrow$HREDに、VAE(バエと呼ばれている)の潜在変数の概念を追加したもの。
    • HREDの課題を、VAEの潜在変数の概念を追加することで解決した構造。
  • 5-5VAE

  • 5-5-1オートエンコーダ―

    • オートエンコーダとは?$\Rightarrow$教師なし学習の一つ。そのため学習時の入力データは訓練データのみで教師データは利用しない。
    • オートエンコーダ具体例MNISTの場合、28x28の数字の画像を入れて、同じ画像を出力するニューラルネットワークということになります。
    • オートエンコーダ構造
    • 構造図
      スクリーンショット 2020-01-03 22.40.52.png
    • オートエンコーダ構造説明$\Rightarrow$入力データから潜在変数zに変換するニューラルネットワークをEncoder逆に潜在変数zをインプットとして元画像を復元するニューラルネットワークをDecoder。
    • メリット$\Rightarrow$次元削減が行えること※zの次元が入力データより小さい場合、次元削減とみなすことができる。
  • 5-5-2VAE

    • 通常のオートエンコーダーの場合、何かしら潜在変数zにデータを押し込めているものの、その構造がどのような状態かわからない。
    • VAEはこの潜在変数zに確率分布z∼N(0,1)を仮定したもの。
    • VAEは、データを潜在変数zの確率分布という構造に押し込めることを可能にします。
    • VAE構造図
    • スクリーンショット 2020-01-04 1.23.37.png

Section6)Word2vec

  • 学習データからボキャブラリを作成 Ex) I want to eat apples. I like apples.{apples,eat,I,like,to,want}※わかりやすく7語のボキャブラリを作成したら本来は、辞書の単語数だけできあがる。
  • メリット
    • 大規模データの分散表現の学習が、現実的な計算速度とメモリ量で実現可能にした。
    • ✗:ボキャブラリ×ボキャブラリだけの重み行列が誕生。
    • ○:ボキャブラリ×任意の単語ベクトル次元で重み行列が誕生
    • ###Section7)AttentionMechanism
  • 課題:seq2seq の問題は長い文章への対応が難しいです。seq2seq では、2単語でも、100単語でも、固定次元ベクトルの中に入力しなければならない

  • 解決策:文章が長くなるほどそのシーケンスの内部表現の次元も大きくなっていく、仕組みが必要になります。
    +「入力と出力のどの単語が関連しているのか」の関連度を学習する仕組み

  • Attention Mechanism具体例$\Rigtharrow$※「a」については、そもそも関連度が低く、「I」については「私」との関連度が高い.

  • スクリーンショット 2020-01-04 2.05.31.png

確認テスト

【P11】確認テスト
サイズ5×5の入力画像を、サイズ3×3のフィルタで畳み込んだ時の出力画像のサイズを答えよ。なおストライドは2、パディングは1とする。
⇒【考察】 答え 3✖️3
入力サイズ高さ(H),入力サイズ幅(W)
Output Hight(OH)
Output Width(OW)
Filler Hight(FH)
Filler Width(FW)
ストライド(S)
パンディング(P)

【P12】連鎖律の原理を使い、dz/dxを求めよ。

     z = t^2,t=x+y

⇒【考察】
次のような計算にて求める事ができる。

 \frac{dz}{dx}=\frac{dz}{dy}\frac{dy}{dx}
,t=x+y
z = t^2なのでtで微分すると \frac{dz}{dt}=2t

t=x+yなのでxで微分すると \frac{dt}{dx}=1

\frac{dz}{dx}=2t・1=2t=2(x+y)
   OH =\frac{H+2P-FH}{S}+1 =\frac{5+2・1-3}{2}+1=3
   OH =\frac{W+2P-FW}{S}+1 =\frac{5+2・1-3}{2}+1=3

決まった計算方法なので、公式として覚えておこう。

【P23】確認テスト
RNNのネットワークには大きくわけて3つの重みがある。1つは入力から現在の中間層を定義する際にかけられる重み、1つは中間層から出力を定義する際にかけられる重みである。残り1つの重みについて説明せよ。
⇒【考察】 
答えは、中間層から次の中間層へ渡される重み。
スクリーンショット 2020-01-03 6.53.48.png

【P37】連鎖律の原理を使い、dz/dxを求めよ。

     z = t^2,t=x+y

⇒【考察】
次のような計算にて求める事ができる。

 \frac{dz}{dx}=\frac{dz}{dy}\frac{dy}{dx}
,t=x+y
z = t^2なのでtで微分すると \frac{dz}{dt}=2t

t=x+yなのでxで微分すると \frac{dt}{dx}=1

\frac{dz}{dx}=2t・1=2t=2(x+y)

【P46】確認テスト

下図のy1をx・s0・s1・win・w・woutを用いて数式で表せ。※バイアスは任意の文字で定義せよ。※また中間層の出力にシグモイド関数g(x)を作用させよ。

Z_1=sigmoid(S_0W+x_1W_{(in)}+b)

出力層もシグモイドを使う

y_1=sigmoid(Z_1W_{(out)}+c)

書物によって記号の書き方が違うので、本質を知る。

【P54】コード演習問題
スクリーンショット 2020-01-03 13.43.56.png
⇒【考察】答えは(2)
【解説】RNNでは中間層出力h_{t}が過去の中間層出力h_{t-1},.., h_{1}に依存する。RNNにおいて損失関数を重みWやUに関して偏微分するときは、それを考慮する必要があり、dh_{t}/dh_{t-1} = Uであることに注意すると、過去に遡るたびにUが掛けられる。つまり、delta_t= delta_t.dot(U)となる。

【P63】シグモイド関数を微分した時、入力値が0の時に最大値をとる。その値として正しいものを選択肢から選べ。(1)0.15(2)0.25(3)0.35(4)0.45

⇒【考察】
sigumoidの微分

     (sigmoid)'=(1-sigmoid)(sigmoid)

sigmoid関数は0.5で最大となるので、

     (sigmoid)'=(1-0.5)(0.5)=0.25  となる

【P65】演習チャレンジ
スクリーンショット 2020-01-03 14.28.59.png

⇒【考察】
正解:1【解説】勾配のノルムがしきい値より大きいときは、勾配のノルムをしきい値に正規化するので、クリッピングした勾配は、勾配×(しきい値/勾配のノルム)と計算される。つまり、gradient * rateである。
勾配に対して敷居値がかけあわされて正規化されているだけなので理解しやい。

【P79】確認テスト
以下の文章をLSTMに入力し空欄に当てはまる単語を予測したいとする。文中の「とても」という言葉は空欄の予測においてなくなっても影響を及ぼさないと考えられる。このような場合、どのゲートが作用すると考えられるか。「映画おもしろかったね。ところで、とてもお腹が空いたから何か____。」
⇒【考察】
正解:忘却ゲート。
忘却ゲートの役割は,直前の影響をどの程度考慮するかを定めることに利用される。

【P80】演習チャレンジ
スクリーンショット 2020-01-03 16.10.21.png

⇒【考察】
正解:3【解説】新しいセルの状態は、計算されたセルへの入力と1ステップ前のセルの状態に入力ゲート、忘却ゲートを掛けて足し合わせたものと表現される。つまり、input_gate* a + forget_gate* cである。

【P89】確認テスト
LSTMとCECが抱える課題について、それぞれ簡潔に述べよ。

⇒【考察】
LSTMとCECが抱える課題。
LSTMでは、パラメータ数が多く、計算負荷が高い問題があった。
CECでは、学習という概念がなく、重みも利用されていない。保存の過去の情報を、任意のタイミングで他のノードに伝播させたり、あるいは任意のタイミングで忘却させたいニーズに応えられない。

【P91】演習チャレンジ
スクリーンショット 2020-01-03 16.53.16.png

【P93】確認テスト
LSTMとGRUの違いを簡潔に述べよ。
⇒【考察】
LSTMでは、パラメータ数が多く、計算負荷が高い問題があったが、GRUではパラメータも削減され、処理も高速となった。
ただし、全てがGRUがまさっている訳ではなく、場合によって比較選択してゆくのが良い。

【P96】演習チャレンジ

スクリーンショット 2020-01-03 20.20.29.png
⇒【考察】
正解:4【解説】双方向RNNでは、順方向と逆方向に伝播したときの中間層表現をあわせたものが特徴量となるので、np.concatenate([h_f, h_b[::-1]], axis=1)である。
(参考)np.concatenate構文は、こちらで学習

【P111】演習チャレンジ
スクリーンショット 2020-01-03 21.07.54.png
⇒【考察】
正解:1【解説】単語wはone-hotベクトルであり、それを単語埋め込みにより別の特徴量に変換する。これは埋め込み行列Eを用いて、E.dot(w)と書ける。
wはOneーhotベクトルでできている。

(参考)自然言語処理とon-hotの関係は、こちらで学習
文書が大きい時には、on-hotデータも大きくなり、処理が間に合わない場合もありうる課題あり。
【P120】確認テスト
seq2seqとHRED、HREDとVHREDの違いを簡潔に述べよ。
⇒【考察】
seq2seqは一問一答しかできなかったが、HREDはその課題を解決するためにできたもの。HREDとVHREDの違いは、HREDが同じような回答しができない課題があり、その課題を解決し、表現を変えながら回答できるのがVHREDである。

【P129】確認テスト
VAEに関する下記の説明文中の空欄に当てはまる言葉を答えよ。自己符号化器の潜在変数に____を導入したもの
⇒【考察】答えは、潜在変数に『確率変数』を導入したもの。

【P138】確認テスト
RNNとword2vec、seq2seqとAttentionの違いを簡潔に述べよ。
⇒【考察】
RNNは、ボキャブラリー数✖️ボキャブラリー数の重みの行列を生成する必要があったが、word2vecは、ボキャブラリー数✖️任意の単語ベクトル数の重みの行列で作る事ができる。
seq2seqとAttentionでは、seq2seq同じ質問に同じ回答しか出せないが、Attentionでは重要度・関連度が活用でき、バリエーションをもつ回答を返せるようになる。繰り返し学習により精度向上に繋がる回答を出せるようになる。

【ビデオDN60】演習チャレンジ
スクリーンショット 2020-01-04 1.29.38.png
⇒【考察】答えは(2)。
表現ベクトルで表し、レフトとライトで隣接した表現ベクトルに対して重みをつけて計算してゆく。

#演習 

DN42_ソース演習①

simple RNN
バイナリ加算
バイナリ加算の実行結果
スクリーンショット 2020-01-03 4.42.29.png

[try] weight_init_stdやlearning_rate, hidden_layer_sizeを変更してみよう
weight_init_std 1→10
learning_rate 0.1→0.01
hidden_layer_size 16→32
スクリーンショット 2020-01-03 4.53.56.png
かなり学習が悪くなった。

[try] 重みの初期化方法を変更してみよう
Xavier, Heのどちらも変えて実施してみる。
(ソース変更箇所)

python
###########  変更箇所  ##############
# ウェイト初期化 (バイアスは簡単のため省略)
#W_in = weight_init_std * np.random.randn(input_layer_size, hidden_layer_size)
#W_out = weight_init_std * np.random.randn(hidden_layer_size, output_layer_size)
#W = weight_init_std * np.random.randn(hidden_layer_size, hidden_layer_size)
# Xavierを使ってウェイト初期化
W_in=np.random.randn(input_layer_size,hidden_layer_size)/(np.sqrt(input_layer_size))W_out=np.random.randn(hidden_layer_size,output_layer_size)/(np.sqrt(hidden_layer_size))W=np.random.randn(hidden_layer_size,hidden_layer_size)/(np.sqrt(hidden_layer_size))# Heを使ってウェイト初期化
# W_in = np.random.randn(input_layer_size, hidden_layer_size) / (np.sqrt(input_layer_size)) * np.sqrt(2)
# W_out = np.random.randn(hidden_layer_size, output_layer_size) / (np.sqrt(hidden_layer_size)) * np.sqrt(2)
# W = np.random.randn(hidden_layer_size, hidden_layer_size) / (np.sqrt(hidden_layer_size)) * np.sqrt(2)
#####################################

Xavierを使った結果
スクリーンショット 2020-01-03 5.38.13.png
HEを使った結果
スクリーンショット 2020-01-03 5.41.19.png
ほぼ近しい結果となった。

[try] 中間層の活性化関数を変更してみよう
ReLU(勾配爆発を確認しよう)

python変更点
#  z[:,t+1] = functions.sigmoid(u[:,t+1])
z[:,t+1]=functions.relu(u[:,t+1])#  z[:,t+1] = functions.np.tanh(u[:,t+1])

スクリーンショット 2020-01-03 5.55.44.png

tanh(numpyにtanhが用意されている。導関数をd_tanhとして作成しよう)

python変更点 導関数の定義追加
defd_tanh(x):returnnp.tanh(x)
python変更点
#  z[:,t+1] = functions.sigmoid(u[:,t+1])
#  z[:,t+1] = functions.relu(u[:,t+1])
z[:,t+1]=d_tanh(u[:,t+1])

スクリーンショット 2020-01-03 6.00.26.png

深層学習: Day2 CNN

$
0
0

sutudy-ai


<科目> 深層学習 

目次
深層学習: Day1 NN
深層学習: Day2 CNN
深層学習: Day3 RNN
深層学習: Day4 強化学習・Tensor Flow

深層学習: Day2 CNN (講義の要約)

深層学習全体像の復習–学習概念

  1. 入力層に値を入力
  2. 重み、バイアス、活性化関数で計算しながら値が伝わる
  3. 出力層から値が伝わる
  4. 出力層から出た値と正解値から、誤差関数を使って誤差を求める
  5. 誤差を小さくするために重みやバイアスを更新する.(特に重要である)
  6. 1〜5の操作を繰り返すことにより、出力値を正解値に近づけていく

    スクリーンショット 2020-01-02 10.07.45.png
    誤差逆伝播のイメージ図
    スクリーンショット 2020-01-02 10.12.55.png
    スクリーンショット 2020-01-02 10.36.12.png
    スクリーンショット 2020-01-02 10.38.48.png
    スクリーンショット 2020-01-02 10.39.04.png

メリットとして、誤差の計算結果から微分を逆算することで、不要な再帰的計算を避けて微分を算出できる。計算コストの削減。

深層モデルのための学習テクニック

  • Section1) 勾配消失問題について全体像

    (前回の流れと課題全体像のビジョン)
       勾配消失問題
       誤差逆伝播法が下位層に進んでいくに連れて、勾配がどんどん緩やかになっていく。そのため、勾配降下法による、更新では下位層のパラメータはほとんど変わらず、訓練は最適値に収束しなくなる。シグモイド関数→(問題)大きな値では出力の変化が微小なため、勾配消失問題を引き起こす事があった。

    • 1-1活性化関数
      ReLU関数
          勾配消失問題の回避とスパース化に貢献することで良い成果をもたらしている。
          ※勾配消失問題・スパース化については確率的勾配降下法の解説後に詳しく触れる予定
    • 1-2初期値の設定方法

      重みの初期値設定-Xavier

      Xavierの初期値を設定する際の活性化関数
      ReLU関数
      シグモイド(ロジスティック)関数
      双曲線正接関数
      スクリーンショット 2020-01-02 11.01.51.png

         **重みの初期値設定-He**
      

      Heの初期値を設定する際の活性化関数
      Relu関数
      スクリーンショット 2020-01-02 11.04.56.png
      初期値の設定方法
      重みの要素を、前の層のノード数の平方根で除算した値に対し、ルート2を掛け合わせた値。

    • 1-3バッチ正規化

      バッチ正規化とは$\Rightarrow$ミニバッチ単位で、入力値のデータの偏りを抑制する手法
      

      バッチ正規化の使い所とは︖$\Rightarrow$活性化関数に値を渡す前後に、バッチ正規化の処理を孕んだ層を加える

u^{(l)}=w^{(l)}z^{(l)}+b^{(l)}  または z

スクリーンショット 2020-01-02 11.52.05.png
スクリーンショット 2020-01-02 11.52.18.png
スクリーンショット 2020-01-02 11.52.54.png

  • Section2)学習率最適化手法について全体像
    (前回の流れと課題全体像のビジョン)

    + 勾配降下法の復習
スクリーンショット 2020-01-02 12.01.44.png
+ 学習率の復習学
習率の値が大きい場合・最適値にいつまでもたどり着かず発散してしまう。学習率の値が小さい場合・発散することはないが、小さすぎると収束するまでに時間がかかってしまう。
・大域局所最適値に収束しづらくなる。

  • Section2)続き(図が入るとインデントが崩れてしまう?)

    • 2-1モメンタム
    • スクリーンショット 2020-01-02 12.14.11.png
    • スクリーンショット 2020-01-02 12.15.29.png
    • 2-2AdaGrad
    • スクリーンショット 2020-01-02 12.16.20.pngスクリーンショット 2020-01-02 12.16.36.png
    • 2-3 RMSProp
    • スクリーンショット 2020-01-02 12.17.21.pngスクリーンショット 2020-01-02 12.17.42.png
    • 2-4Adam
      • Adamとは︖$\Rightarrow$モメンタムの、過去の勾配の指数関数的減衰平均・RMSPropの、過去の勾配の2乗の指数関数的減衰平均上記をそれぞれ孕んだ最適化アルゴリズムである。
      • Adamのメリットとは︖$\Rightarrow$モメンタムおよびRMSPropのメリットを孕んだアルゴリズムである。
  • Section3)過学習について全体像
    (前回の流れと課題全体像のビジョン)
    テスト誤差と訓練誤差とで学習曲線が乖離すること。︖$\Rightarrow$特定の訓練サンプルに対して、特化して学習する。
    原因は、パラメータの数が多い、パラメータの値が適切でない、ノードが多いetc...
    $\Rightarrow$ネットワークの自由度(層数、ノード数、パラメータの値etc...)が高い

    • 3-1 L1正則化、L2正則化

      正則化とは︖︖$\Rightarrow$ネットワークの自由度(層数、ノード数、パラメータ値etc...)を制約すること。
      ︖$\Rightarrow$正則化手法を利用して過学習を抑制する

      • Weight decay(荷重減衰)
        • 過学習の原因
        • 重みが大きい値をとることで、過学習が発生することがある。
        • 重みが大きい値は、学習において重要な値であり、重みが大きいと過学習が起こる。
        • 過学習の解決策
        • 誤差に対して、正則化項を加算することで、重みを抑制する学習させていくと、重みにばらつきが発生する。
        • 過学習がおこりそうな重みの大きさ以下で重みをコントロールし、かつ重みの大きさにばらつきを出す必要がある。
    • 3-2ドロップアウト

    • 過学習の課題・ノードの数が多いドロップアウトとは︖$\Rightarrow$ランダムにノードを削除して学習させること。メリットとして、データ量を変化させずに、異なるモデルを学習させていると解釈できる。

    • スクリーンショット 2020-01-02 13.59.09.png

畳み込みニューラルネットワークについて

  • 畳み込みニューラルネットワークについて

    • Section4)畳み込みニューラルネットワークの概念

      CNNの構造図

      スクリーンショット 2020-01-02 14.09.10.png

      LeNetの構造図

      スクリーンショット 2020-01-02 14.11.19.png

      • 4-1畳み込み層
      • 4-1-1バイアス
      • 畳み込み層演算概念(バイアス)
      • スクリーンショット 2020-01-02 14.16.56.png
      • 4-1-2パディング
      • 畳み込み層演算概念(パディング)
      • スクリーンショット 2020-01-02 14.18.01.png
      • 4-1-3ストライド
      • 畳み込み層演算概念(パディング)
      • スクリーンショット 2020-01-02 14.20.18.png
      • 4-1-4チャンネル
      • 畳み込み層演算概念(チャンネル)
      • スクリーンショット 2020-01-02 14.21.03.png
      • 全結合で画像を学習した際の課題 全結合層のデメリット$\Rightarrow$画像の場合、縦、横、チャンネルの3次元データだが、1次元のデータとして処理される。$\Rightarrow$RGBの各チャンネル間の関連性が、学習に反映されないということ。
      • 4-2プーリング層
      • プーリング層の概念図
      • スクリーンショット 2020-01-02 14.25.11.png
    • Section5)最新のCNN

      • 5-1 AlexNet
      • AlexNetのモデル説明
      • モデルの構造
        • 5層の畳み込み層およびプーリング層など、それに続く3層の全結合層から構成される。
      • 過学習を防ぐ施策
        • サイズ4096の全結合層の出力にドロップアウトを使用している。
        • スクリーンショット 2020-01-02 14.50.59.png

演習

DN06_Jupyter演習

確認テストの考察

【P12】連鎖律の原理を使い、dz/dxを求めよ。

     z = t^2,t=x+y

⇒【考察】
次のような計算にて求める事ができる。

 \frac{dz}{dx}=\frac{dz}{dy}\frac{dy}{dx}
,t=x+y
z = t^2なのでtで微分すると \frac{dz}{dt}=2t

t=x+yなのでxで微分すると \frac{dt}{dx}=1

\frac{dz}{dx}=2t・1=2t=2(x+y)

【P20】シグモイド関数を微分した時、入力値が0の時に最大値をとる。その値として正しいものを選択肢から選べ。(1)0.15(2)0.25(3)0.35(4)0.45

⇒【考察】
sigumoidの微分

     (sigmoid)'=(1-sigmoid)(sigmoid)

sigmoid関数は0.5で最大となるので、

     (sigmoid)'=(1-0.5)(0.5)=0.25  となる

【P28】重みの初期値に0を設定すると、どのような問題が発生するか。簡潔に説明せよ。
⇒【考察】
勾配が得られない場合がある。前述で重みの初期値の公式が挙げられたので活用してゆく。

【P31】一般的に考えられるバッチ正規化の効果を2点挙げよ。
⇒【考察】
  中間層のパラメータの分布が適切になる。
  中間層の学習が安定化する
この手法は2015年に提案された新しい手法であるにもかかわらず現在広く使われてる。.

【P36】例題チャレンジ
スクリーンショット 2020-01-02 11.54.43.png

正解:data_x[i:i_end], data_t[i:i_end
•【解説】バッチサイズだけデータを取り出す処理である。
⇒【考察】記載が似通って、間違いやすいので気をつけよう。

【P63】確認テスト

スクリーンショット 2020-01-02 12.38.45.png

⇒【考察】
答えは「a」
スクリーンショット 2020-01-02 12.50.27.png
図と一緒に覚えると良い。

【P68】L1正則化を表しているグラフはどちらか答えよ。
⇒【考察】
答えは右
スクリーンショット 2020-01-02 12.37.49.png

図と一緒に覚えると良い。Lassoは菱形が特徴的な図である。(Ridgeは円形)

【P69】例題チャレンジ

スクリーンショット 2020-01-02 13.31.21.png

⇒【考察】
答えは(4)param
スクリーンショット 2020-01-02 13.40.33.png
計算式と一緒に憶えると良い。L1 ,L2を正しく理解する。

【P71】例題チャレンジ

スクリーンショット 2020-01-02 13.44.02.png

⇒【考察】
答えは『sign(param)』
【解説】L1ノルムは、|param|なのでその勾配が誤差の勾配に加えられる。つまり、sign(param)である。signは符号関数である。
初めて出る、sign符号関数についても理解が必要。

【P78】例題チャレンジ
スクリーンショット 2020-01-02 13.53.49.png
⇒【考察】
 正解:image[top:bottom, left:right, :]
【解説】imageの形式が(縦幅, 横幅, チャンネル)であるのも考慮する。

【P100】確認テスト
サイズ6×6の入力画像を、サイズ2×2のフィルタで畳み込んだ時の出力画像のサイズを答えよ。なおストライドとパディングは1とする。
⇒【考察】
答え 7✖️7
入力サイズ高さ(H),入力サイズ幅(W)
Output Hight(OH)
Output Width(OW)
Filler Hight(FH)
Filler Width(FW)
ストライド(S)
パンディング(P)

   OH =\frac{H+2P-FH}{S}+1 =\frac{6+2・1-2}{1}-1=7
   OH =\frac{W+2P-FW}{S}+1 =\frac{6+2・1-2}{1}-1=7

決まった計算方法なので、公式として覚えておくと便利。

演習

DN23_Jupyter演習

スクリーンショット 2020-01-02 15.46.59.png

ReLU-Xavierの組み合わせに変更した結果
スクリーンショット 2020-01-02 15.36.15.png
Sigmoid-HEの組み合わせに変更した結果
スクリーンショット 2020-01-02 15.43.35.png

DN32_Jupyter演習(Dropout)

スクリーンショット 2020-01-03 2.28.29.png
スクリーンショット 2020-01-03 2.31.55.png

DN35_Jupyter演習(im2col)

[try] im2colの処理を確認しよう
・関数内でtransposeの処理をしている行をコメントアウトして下のコードを実行してみよう
・input_dataの各次元のサイズやフィルターサイズ・ストライド・パディングを変えてみよう

⇒【考察】
演習結果は次のとうり。

python
# im2colの処理確認
input_data=np.random.rand(2,1,4,4)*100//1# number, channel, height, widthを表す
print('========== input_data ===========\n',input_data)print('==============================')filter_h=3filter_w=3stride=1pad=0col=im2col(input_data,filter_h=filter_h,filter_w=filter_w,stride=stride,pad=pad)print('============= col ==============\n',col)print('==============================')

スクリーンショット 2020-01-03 3.05.36.png

以下のようにinput_dataの各次元のサイズやフィルターサイズ・ストライド・パディングを変えてみる。

python
filter_h=6filter_w=6stride=2pad=1

スクリーンショット 2020-01-03 3.11.05.png

・im2colとcol2imでは全く同じように戻る訳ではないことを理解した上で利用する必要がある。
・そもそも使うシーンが違う。im2colは畳み込み時に利用するが、col2imは最終的な出力に利用される。

[try] col2imの処理を確認しよう
・im2colの確認で出力したcolをimageに変換して確認しよう

⇒【考察】

python
# col2imの処理を追加
img=col2im(col,input_shape=input_data.shape,filter_h=filter_h,filter_w=filter_w,stride=stride,pad=pad)print(img)

スクリーンショット 2020-01-03 3.23.19.png

DN37_Jupyter演習(3)

スクリーンショット 2020-01-03 3.30.52.png

・畳み込み処理は学習するのに時間がかかるので注意が必要。ストレスなく処理するには、PCスペックを上げたり、GPU搭載した機器を用意するのをお勧めします。

深層学習: Day1 NN

$
0
0

sutudy-ai


<科目> 深層学習 

深層学習: Day1 NN
深層学習: Day2 CNN
深層学習: Day3 RNN
深層学習: Day4 強化学習・Tensor Flow

深層学習: Day1 NN (講義の要約)

  • ニューラルネットワーク(NN)でできること
  • 回帰

    • 結果予想
      • 株価予想
      • 売上予想
    • ランキング
      • 競馬順位予想
      • 人気順位予想
  • 分類

    • 猫写真の判別
    • 手書き文字認識
    • 花の種類分類
  • ニューラルネットワーク︓回帰(連続する実数値を取る関数の近似)

  • 【回帰分析】
    •線形回帰
    •回帰木
    •ランダムフォレスト
    •ニューラルネットワーク(NN)

  • ニューラルネットワーク︓分類(性別(男or女)や動物の種類
    など離散的な結果を予想するための分析)

  • 【分類分析】
    •ベイズ分類
    •ロジスティック回帰
    •ランダムフォレスト
    •ニューラルネットワーク(NN)

Section1) 入力層〜中間層

NN01.jpg

NN02.jpg

  • 重みをラージWであらわして、バイアスbで表して、両方を合わせて示唆する場合は、スモールwで表しているのがややこしいポイント。
  • 中間層は無限に設定できる。

Section2) 活性化関数

  • ニューラルネットワークにおいて、次の層への出力の大きさを決める非線形の関数。
  • 入力値の値によって、次の層への信号のON/OFFや強弱を定める働きを持つ。
  • 中間層用の活性化関数
    • ステップ関数

   数式

f(x) = \left\{
\begin{array}{ll}
1 & (x \geq 0) \\
0 & (x \lt 0)
\end{array}
\right.
python
defstep_function(x):ifx>0:return1else:return0
  • シグモイド(ロジスティック)関数

   数式

f(u) =  \frac{1}{1+e^{-u}}

python
defsigmoid(x):return1/(1+np.exp(-x))

0 ~ 1の間を緩やかに変化する関数で、ステップ関数ではON/OFFしかない状態に対し、信号の強弱を伝えられるようになり、予想ニューラルネットワーク普及のきっかけとなった。
課題
大きな値では出力の変化が微小なため、勾配消失問題を引き起こす事があった。

  • ReLU関数
f(x) = \left\{
\begin{array}{ll}
x & (x \gt 0) \\
0 & (x \leq 0)
\end{array}
\right.
python
defrelu(x):returnnp.maximum(0,x)

今最も使われている活性化関数
勾配消失問題の回避とスパース化に貢献することで良い成果をもたらしている。
※ 勾配消失問題
・スパース化については確率的勾配降下法の解説後に詳しく触れる予定
+ 出力層用の活性化関数
+ ソフトマックス関数
+ 恒等写像
+ シグモイド関数(ロジスティック関数)

Section3) 出力層

3-1 誤差関数

nn04.jpg
誤差の計算 誤差関数= 二乗誤差の場合

En(w)=\frac{1}{2}\sum_{j=1}^{I} (y_j-d_j)^2 = \frac{1}{2}||(y-d)||^2

3-2 出力層の活性化関数

  • 出力層の中間層との違い
    • 【値の強弱】
      • 中間層︓しきい値の前後で信号の強弱を調整
      • 出力層︓信号の大きさ(比率)はそのままに変換
    • 【確率出力】
      • 分類問題の場合、出力層の出力は0 ~ 1 の範囲に限定し、総和を1とする必要がある
    • 出力層と中間層で利用される活性化関数が異なる nn05.jpg
  • 交差エントロピー
En(w)=-\sum_{i=1}^Id_ilog y_i
python
# クロスエントロピー
defcross_entropy_error(d,y):ify.ndim==1:d=d.reshape(1,d.size)y=y.reshape(1,y.size)# 教師データがone-hot-vectorの場合、正解ラベルのインデックスに変換
ifd.size==y.size:d=d.argmax(axis=1)batch_size=y.shape[0]return-np.sum(np.log(y[np.arange(batch_size),d]+1e-7))/batch_size

One-hot ベクトルとは、(0,1,0,0,0,0) のように、1つの成分が1で残りの成分が全て0であるようなベクトルのことです。
(参考)One-hotベクトルとはで調べたサイト

Section4) 勾配降下法

  • 勾配降下法
    • 全結合NN–勾配降下法
      • 学習を通して誤差を最小にするネットワークを作成すること
      • 誤差E(w)を最小化するパラメータの発見が目的
      • 勾配降下法を利用してパラメータを最適化
      • 学習率$\varepsilon$によって学習の効果が大きく変わる
      • $W^{(t+1)} =W^{(t)}-\varepsilon\nabla E (\varepsilon は学習率)$
        $\nabla E=\frac{\partial E}{\partial W}=[\frac{\partial E}{\partial w_1}・・・\frac{\partial E}{\partial w_M}]$
        勾配降下法の学習率の決定、収束性向上のためのアルゴリズムについて複数の 論文が公開されている
        • Momentum
        • AdaGrad
        • Adadelta
        • Adam

   (参考)勾配降下法の解説サイト

  • 確率的勾配降下法
    • $W^{(t+1)} =W^{(t)}-\varepsilon\nabla E (\varepsilon は学習率)$・・・勾配降下法
      勾配降下法は全サンプルの平均誤差
    • $W^{(t+1)} =W^{(t)}-\varepsilon\nabla En (\varepsilon は学習率)$・・・確率的勾配降下法
      確率的勾配降下法は、ランダムに抽出したサンプルの誤差
    • 確率的勾配降下法のメリット
      • データが冗⻑な場合の計算コストの軽減
      • 望まない局所極小解に収束するリスクの軽減
      • オンライン学習ができる
    • (参考)確率的勾配降下法の解説サイト
  • ミニバッチ勾配降下法

    • $W^{(t+1)} =W^{(t)}-\varepsilon\nabla En (\varepsilon は学習率)$・・・確率的勾配降下法
      確率的勾配降下法は、ランダムに抽出したサンプルの誤差
    • $W^{(t+1)} =W^{(t)}-\varepsilon\nabla Et (\varepsilon は学習率)$・・・ミニバッチ勾配降下法
      $E_t=\frac{1}{N_t}\sum_{n\in D_t}E_n$
      $N_t=|D_t|$

    ミニバッチ勾配降下法は、ランダムに抽出したデータの集合()ミニバッチ)$D_t$に属するサンプルの平均誤差

    ミニバッチ勾配降下法のメリット
    確率的勾配降下法のメリットを損なわず、計算機の計算資源を有効利用できる
    → CPUを利用したスレッド並列化やGPUを利用したSIMD並列化

Section5) 誤差逆伝播法

誤差勾配の計算–誤差逆伝播法
【誤差逆伝播法】算出された誤差を、出力層側から順に微分し、前の層前の層へと伝播。最小限の計算で各パラメータでの微分値を解析的に計算する手法
nn07.jpg
nn08.jpg
計算結果(=誤差)から微分を逆算することで、不要な再帰的計算を避けて微分を算出できる
nn09.jpg

python
# 誤差逆伝播
defbackward(x,d,z1,y):print("\n##### 誤差逆伝播開始 #####")grad={}W1,W2=network['W1'],network['W2']b1,b2=network['b1'],network['b2']#  出力層でのデルタ
delta2=functions.d_sigmoid_with_loss(d,y)#  b2の勾配
grad['b2']=np.sum(delta2,axis=0)#  W2の勾配
grad['W2']=np.dot(z1.T,delta2)#  中間層でのデルタ
delta1=np.dot(delta2,W2.T)*functions.d_relu(z1)# b1の勾配
grad['b1']=np.sum(delta1,axis=0)#  W1の勾配
grad['W1']=np.dot(x.T,delta1)print_vec("偏微分_dE/du2",delta2)print_vec("偏微分_dE/du2",delta1)print_vec("偏微分_重み1",grad["W1"])print_vec("偏微分_重み2",grad["W2"])print_vec("偏微分_バイアス1",grad["b1"])print_vec("偏微分_バイアス2",grad["b2"])returngrad

確認テストの考察

【P10】ディープラーニングは、結局何をやろうとしているか2行以内で述べよ。 また、次の中のどの値の最適化が最終目的か。 全て選べ。
①入力値[ X] ②出力値[ Y] ③重み[W]④バイアス[b] ⑤総入力[u] ⑥中間層入力[ z] ⑦学習率[ρ]

⇒【考察】ディープラーニングは、結局、誤差を最小化するパラメータを確定することを目的としている。どの値の最適化が最終目的かというと③重み[W] ④バイアス[b]を最適化しようとしている。

【P12】次のネットワークを紙にかけ。

  • 入力層︓2ノード1層
  • 中間層︓3ノード2層
  • 出力層: 1ノード1層

⇒【考察】
IMG_2280.jpg
自分で書いてみると、分かりやすい。

【P19】確認テスト
    この図式に動物分類の実例を入れてみようp19.gif

⇒【考察】
p19.jpg

【P21】確認テスト

この式をpythonで書け

u=w_1x_1+w_2x_2+w_3x_3+w_4x_4+b=Wx+b..(1.2)

⇒【考察】

pyhon
u1=np.dot(x,W1)+b1

【P23】確認テスト
   中間層を表すコードを抜き出せ

⇒【考察】

pyhon
#隠れ層の総入力
u1=np.dot(x,W1)+b1#隠れ層の総出力
z1=functions.relu(u1)
  • RELU関数は別途解説。

【P26】確認テスト
   線形と非線形の違いを図にかいて簡易に説明せよ。

IMG_0101.jpg

【P34】確認テスト
全結合NN-単層・複数ノード
nn03.jpg
配布されたソースコードより該当する箇所を抜き出せ。
⇒【考察】
活性化関数f(u)がシグモイド関数なのでこの部分となる。

python
z1=functions.sigmoid(u)

【P34】確認テスト
誤差の計算 誤差関数= 二乗誤差の場合

En(w)=\frac{1}{2}\sum_{j=1}^{I} (y_j-d_j)^2 = \frac{1}{2}||(y-d)||^2

・なぜ、引き算でなく二乗するか述べよ
・下式の1/2はどういう意味を持つか述べよ

⇒【考察】
・分散をプラスで表すため
・1/2は平均値をとっている
(参考)ここのサイトがわかりやすかった
最小二乗法の意味と計算方法 - 回帰直線の求め方

※本来ならば分類問題の場合誤差関数にクロスエントロピー誤差を用いるのでコードは
loss =cross_entropy_error(d,y)
となるが今回は説明の便宜上誤差関数に平均二乗誤差を用いているためコードは
loss = functions.mean_squared_error(d, y)
となる

【P51】確認テスト(S3_2 出力層_活性化関数)
ソフトマックス関数

①f(i,u)=\frac{e^{u_i}②}{\sum_{k=1}^{k}e^{u_k}③}

①~③の数式に該当するソースコードを示し、一行ずつ説明せよ

python
defsoftmax(x):ifx.ndim==2:#2次元だった場合
x=x.Txx=x-np.max(x,axis=0)y=np.exp(x)/np.sum(np.exp(x),axis=0)returny.Tx=x-np.max(x)# オーバーフロー対策
returnnp.exp(x)/np.sum(np.exp(x))

①・・・・y(return y.Tより転置を返している)
②・・・・np.exp(x) 部分
③・・・・np.sum(np.exp(x), axis=0) 部分

(学習参考)NumPyの軸(axis)と次元数(ndim)とは何を意味するのか
```
【P53】確認テスト(S3_2 出力層_活性化関数)
交差エントロピー
①~②の数式に該当するソースコードを示し、一行づつ処理の説明をせよ。

En(w)=-\sum_{i=1}^Id_ilog y_i

$En(w)$・・・①の部分
$-\sum_{i=1}^Id_ilog y_i$・・・②の部分

⇒【考察】
・return-np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size
・1/2は平均値をとっている

python
# クロスエントロピー
defcross_entropy_error(d,y):ify.ndim==1:d=d.reshape(1,d.size)y=y.reshape(1,y.size)# 教師データがone-hot-vectorの場合、正解ラベルのインデックスに変換
ifd.size==y.size:d=d.argmax(axis=1)batch_size=y.shape[0]return-np.sum(np.log(y[np.arange(batch_size),d]+1e-7))/batch_size

$En(w)$・・・①の部分 はreturn値
$-\sum_{i=1}^Id_ilog y_i$・・・②の部分
-np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_sizeの部分。

  • 『1e-7』を足しているのは、log部分がゼロにならないように微細な数字を足している。
  • 教師データがone-hotベクトルの場合かそうでない場合(教師データが整数など)か重要。one-hotベクトルでない場合はkerasを利用した別関数を使う必要がある。

【P56】確認テスト(S4 勾配降下法)
勾配降下法関数の該当するソースコードを探してみよう。

$W^{(t+1)} =W^{(t)}-\varepsilon\nabla E_n (\varepsilon は学習率)$・・・・①
$\nabla E=\frac{\partial E}{\partial W}=[\frac{\partial E}{\partial w_1}・・・\frac{\partial E}{\partial w_M}]$・・・・②

⇒【考察】

python
# 誤差
loss=functions.cross_entropy_error(d,y)grad=backward(x,d,z1,y)# ②の部分にあたる
forkeyin('W1','W2','b1','b2'):network[key]-=learning_rate*grad[key] # ①の部分にあたる

【P65】確認テスト(S4 勾配降下法)
オンライン学習とは何かまとめよ。
⇒【考察】
オンライン学習とは、新しく取得したデータのみで学習モデルが作成できること。既存のデータを活用せずとも回すことができる。

【P69】確認テスト(S4 勾配降下法)
この数式の意味を図に書いて説明せよ。
+
$W^{(t+1)} =W^{(t)}-\varepsilon\nabla Et (\varepsilon は学習率)$・・・ミニバッチ勾配降下法

⇒【考察】
(〇〇〇) (〇〇〇) (〇〇〇)
   セット1 セット2  セット3
  この場合、任意のデータセット1つをミニバッチの集合として誤差を足し合わせ、1/3する。 
  $E_t=\frac{1}{N_t}\sum_{n\in D_t}E_n$
   $N_t=|D_t|$

【P78】確認テスト(S5 誤差逆伝播法)
誤差逆伝播法では不要な再帰的処理を避ける事が出来る。既に行った計算結果を保持しているソースコードを抽出せよ。

python
# 誤差逆伝播
defbackward(x,d,z1,y):print("\n##### 誤差逆伝播開始 #####")grad={}W1,W2=network['W1'],network['W2']b1,b2=network['b1'],network['b2']#  出力層でのデルタ ##ここでシグモイド関数とクロスエントロピーを合わせた関数の導関数を算出、『delta2』に代入
delta2=functions.d_sigmoid_with_loss(d,y)#  b2の勾配 ## 『delta2』を利用している
grad['b2']=np.sum(delta2,axis=0)#  W2の勾配 ## 『delta2』を利用している
grad['W2']=np.dot(z1.T,delta2)#  中間層でのデルタ ## 『delta2』を利用している
delta1=np.dot(delta2,W2.T)*functions.d_relu(z1)# b1の勾配
grad['b1']=np.sum(delta1,axis=0)#  W1の勾配
grad['W1']=np.dot(x.T,delta1)print_vec("偏微分_dE/du2",delta2)print_vec("偏微分_dE/du2",delta1)print_vec("偏微分_重み1",grad["W1"])print_vec("偏微分_重み2",grad["W2"])print_vec("偏微分_バイアス1",grad["b1"])print_vec("偏微分_バイアス2",grad["b2"])returngrad

【P83】2つの空欄に該当するソースコードを探せ(S5 誤差逆伝播法)
$\frac{\partial E}{\partial y}$ $\frac{\partial y}{\partial u}$

python
# 出力層でのデルタ
delta2=functions.d_mean_squared_error(d,y)

$\frac{\partial E}{\partial y}$ $\frac{\partial y}{\partial u}$ $\frac{\partial u}{\partial w _{ji}^{(2)}}$

python
# 出力層でのデルタ
# W2の勾配
grad['W2']=np.dot(z1.T,delta2)

演習

DN06_Jupyter演習

python
######################################
#   試してみよう                       #
######################################
# 順伝播(単層・単ユニット)
# 重み
#W = np.array([[0.1], [0.2]])
## 試してみよう_配列の初期化
#W = np.zeros(2)
W=np.ones(2)#こちらを選択
#W = np.random.rand(2)
#W = np.random.randint(5, size=(2))
print_vec("重み",W)# バイアス
#b = 0.5
## 試してみよう_数値の初期化
b=np.random.rand()# 0~1のランダム数値       #こちらを選択
#b = np.random.rand() * 10 -5  # -5~5のランダム数値
print_vec("バイアス",b)# 入力値
x=np.array([2,3])print_vec("入力",x)# 総入力
u=np.dot(x,W)+bprint_vec("総入力",u)# 中間層出力
z=functions.relu(u)print_vec("中間層出力",z)

*** 重み ***
[1. 1.]

*** バイアス ***
0.15691869859919338

*** 入力 ***
[2 3]

*** 総入力 ***
5.156918698599194

*** 中間層出力 ***
5.156918698599194

python
######################################
#   試してみよう                       #
######################################
# 順伝播(単層・複数ユニット)
# 重み
#W = np.array([
[0.1,0.2,0.3],[0.2,0.3,0.4],[0.3,0.4,0.5],[0.4,0.5,0.6]#  ])
## 試してみよう_配列の初期化
#W = np.zeros((4,3))
W=np.ones((4,3))#こちらを選択
#W = np.random.rand(4,3)
#W = np.random.randint(5, size=(4,3))
print_vec("重み",W)# バイアス
b=np.array([0.1,0.2,0.3])print_vec("バイアス",b)# 入力値
x=np.array([1.0,5.0,2.0,-1.0])print_vec("入力",x)#  総入力
u=np.dot(x,W)+bprint_vec("総入力",u)# 中間層出力
z=functions.sigmoid(u)print_vec("中間層出力",z)

*** 重み ***
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]

*** バイアス ***
[0.1 0.2 0.3]

*** 入力 ***
[ 1. 5. 2. -1.]

*** 総入力 ***
[7.1 7.2 7.3]

*** 中間層出力 ***
[0.99917558 0.99925397 0.99932492]

python
######################################
#   試してみよう                       #
######################################
# 多クラス分類
# 2-3-4ネットワーク
# !試してみよう_ノードの構成を 3-5-4 に変更してみよう
# ウェイトとバイアスを設定
# ネートワークを作成
definit_network():print("##### ネットワークの初期化 #####")#試してみよう
#_各パラメータのshapeを表示
#_ネットワークの初期値ランダム生成
network={}network['W1']=np.array([[0.1,0.4,0.7,0.1,0.3],[0.2,0.5,0.8,0.1,0.4],[0.3,0.6,0.9,0.2,0.5]])network['W2']=np.array([[0.1,0.6,0.1,0.6],[0.2,0.7,0.2,0.7],[0.3,0.8,0.3,0.8],[0.4,0.9,0.4,0.9],[0.5,0.1,0.5,0.1]])network['b1']=np.array([0.1,0.2,0.3,0.4,0.5])network['b2']=np.array([0.1,0.2,0.3,0.4])print_vec("重み1",network['W1'])print_vec("重み2",network['W2'])print_vec("バイアス1",network['b1'])print_vec("バイアス2",network['b2'])returnnetwork# プロセスを作成
# x:入力値
defforward(network,x):print("##### 順伝播開始 #####")W1,W2=network['W1'],network['W2']b1,b2=network['b1'],network['b2']# 1層の総入力
u1=np.dot(x,W1)+b1# 1層の総出力
z1=functions.relu(u1)# 2層の総入力
u2=np.dot(z1,W2)+b2# 出力値
y=functions.softmax(u2)print_vec("総入力1",u1)print_vec("中間層出力1",z1)print_vec("総入力2",u2)print_vec("出力1",y)print("出力合計: "+str(np.sum(y)))returny,z1## 事前データ
# 入力値
x=np.array([1.,2.,3.])# 目標出力
d=np.array([0,0,0,1])# ネットワークの初期化
network=init_network()# 出力
y,z1=forward(network,x)# 誤差
loss=functions.cross_entropy_error(d,y)## 表示
print("\n##### 結果表示 #####")print_vec("出力",y)print_vec("訓練データ",d)print_vec("誤差",loss)
ネットワークの初期化

*** 重み1 ***
[[0.1 0.4 0.7 0.1 0.3]
[0.2 0.5 0.8 0.1 0.4]
[0.3 0.6 0.9 0.2 0.5]]

*** 重み2 ***
[[0.1 0.6 0.1 0.6]
[0.2 0.7 0.2 0.7]
[0.3 0.8 0.3 0.8]
[0.4 0.9 0.4 0.9]
[0.5 0.1 0.5 0.1]]

*** バイアス1 ***
[0.1 0.2 0.3 0.4 0.5]

*** バイアス2 ***
[0.1 0.2 0.3 0.4]

順伝播開始

*** 総入力1 ***
[1.5 3.4 5.3 1.3 3.1]

*** 中間層出力1 ***
[1.5 3.4 5.3 1.3 3.1]

*** 総入力2 ***
[4.59 9.2 4.79 9.4 ]

*** 出力1 ***
[0.00443583 0.44573018 0.00541793 0.54441607]

出力合計: 1.0

結果表示

*** 出力 ***
[0.00443583 0.44573018 0.00541793 0.54441607]

*** 訓練データ ***
[0 0 0 1]

*** 誤差 ***
0.6080413107681358

python
######################################
#   試してみよう                       #
######################################
#
# 回帰
# 2-3-2ネットワーク
# !試してみよう_ノードの構成を 3-5-4 に変更してみよう
# ウェイトとバイアスを設定
# ネートワークを作成
definit_network():print("##### ネットワークの初期化 #####")network={}network['W1']=np.array([[0.1,0.4,0.7,0.1,0.3],[0.2,0.5,0.8,0.1,0.4],[0.3,0.6,0.9,0.2,0.5]])network['W2']=np.array([[0.1,0.6,0.1,0.6],[0.2,0.7,0.2,0.7],[0.3,0.8,0.3,0.8],[0.4,0.9,0.4,0.9],[0.5,0.1,0.5,0.1]])network['b1']=np.array([0.1,0.2,0.3,0.4,0.5])network['b2']=np.array([0.1,0.2,0.3,0.4])print_vec("重み1",network['W1'])print_vec("重み2",network['W2'])print_vec("バイアス1",network['b1'])print_vec("バイアス2",network['b2'])returnnetwork# プロセスを作成
defforward(network,x):print("##### 順伝播開始 #####")W1,W2=network['W1'],network['W2']b1,b2=network['b1'],network['b2']# 隠れ層の総入力
u1=np.dot(x,W1)+b1# 隠れ層の総出力
z1=functions.relu(u1)# 出力層の総入力
u2=np.dot(z1,W2)+b2# 出力層の総出力
y=u2print_vec("総入力1",u1)print_vec("中間層出力1",z1)print_vec("総入力2",u2)print_vec("出力1",y)print("出力合計: "+str(np.sum(z1)))returny,z1# 入力値
x=np.array([1.,2.,3.])network=init_network()y,z1=forward(network,x)# 目標出力
d=np.array([2.,3.,4.,5.])# 誤差
loss=functions.mean_squared_error(d,y)## 表示
print("\n##### 結果表示 #####")print_vec("中間層出力",z1)print_vec("出力",y)print_vec("訓練データ",d)print_vec("誤差",loss)
ネットワークの初期化

*** 重み1 ***
[[0.1 0.4 0.7 0.1 0.3]
[0.2 0.5 0.8 0.1 0.4]
[0.3 0.6 0.9 0.2 0.5]]

*** 重み2 ***
[[0.1 0.6 0.1 0.6]
[0.2 0.7 0.2 0.7]
[0.3 0.8 0.3 0.8]
[0.4 0.9 0.4 0.9]
[0.5 0.1 0.5 0.1]]

*** バイアス1 ***
[0.1 0.2 0.3 0.4 0.5]

*** バイアス2 ***
[0.1 0.2 0.3 0.4]

順伝播開始

*** 総入力1 ***
[1.5 3.4 5.3 1.3 3.1]

*** 中間層出力1 ***
[1.5 3.4 5.3 1.3 3.1]

*** 総入力2 ***
[4.59 9.2 4.79 9.4 ]

*** 出力1 ***
[4.59 9.2 4.79 9.4 ]

出力合計: 14.6

結果表示

*** 中間層出力 ***
[1.5 3.4 5.3 1.3 3.1]

*** 出力 ***
[4.59 9.2 4.79 9.4 ]

*** 訓練データ ***
[2. 3. 4. 5.]

*** 誤差 ***
8.141525

python
######################################
#   試してみよう                       #
######################################
# 2値分類
# 2-3-1ネットワーク
# !試してみよう_ノードの構成を 5-10-1 に変更してみよう
# ウェイトとバイアスを設定
# ネートワークを作成
definit_network():print("##### ネットワークの初期化 #####")network={}network['W1']=np.array([[0.1,0.3,0.5,0.1,0.3,0.5,0.1,0.3,0.5,0.6],[0.2,0.4,0.6,0.2,0.4,0.6,0.2,0.4,0.6,0.7],[0.2,0.4,0.6,0.2,0.4,0.6,0.2,0.4,0.6,0.7],[0.2,0.4,0.6,0.2,0.4,0.6,0.2,0.4,0.6,0.7],[0.2,0.4,0.6,0.2,0.4,0.6,0.2,0.4,0.6,0.7]])network['W2']=np.array([[0.1],[0.1],[0.1],[0.1],[0.1],[0.1],[0.1],[0.1],[0.1],[0.1]])network['b1']=np.array([0.1,0.3,0.5,0.1,0.3,0.5,0.1,0.3,0.5,0.6])network['b2']=np.array([0.1])returnnetwork# プロセスを作成
defforward(network,x):print("##### 順伝播開始 #####")W1,W2=network['W1'],network['W2']b1,b2=network['b1'],network['b2']# 隠れ層の総入力
u1=np.dot(x,W1)+b1# 隠れ層の総出力
z1=functions.relu(u1)# 出力層の総入力
u2=np.dot(z1,W2)+b2# 出力層の総出力
y=functions.sigmoid(u2)print_vec("総入力1",u1)print_vec("中間層出力1",z1)print_vec("総入力2",u2)print_vec("出力1",y)print("出力合計: "+str(np.sum(z1)))returny,z1# 入力値
x=np.array([1.,2.,3.,4.,5.])# 目標出力
d=np.array([1])network=init_network()y,z1=forward(network,x)# 誤差
loss=functions.cross_entropy_error(d,y)## 表示
print("\n##### 結果表示 #####")print_vec("中間層出力",z1)print_vec("出力",y)print_vec("訓練データ",d)print_vec("誤差",loss)
ネットワークの初期化
順伝播開始

*** 総入力1 ***
[ 3. 6.2 9.4 3. 6.2 9.4 3. 6.2 9.4 11. ]

*** 中間層出力1 ***
[ 3. 6.2 9.4 3. 6.2 9.4 3. 6.2 9.4 11. ]

*** 総入力2 ***
[6.78]

*** 出力1 ***
[0.99886501]

出力合計: 66.8

結果表示

*** 中間層出力 ***
[ 3. 6.2 9.4 3. 6.2 9.4 3. 6.2 9.4 11. ]

*** 出力 ***
[0.99886501]

*** 訓練データ ***
[1]

*** 誤差 ***
0.0011355297129812408
⇒【考察】
中間層の大きさによって出力結果が大きく変わってしまう事がわかった。ユニット数はどうやって決めるのか?中間層の決定はむずかしと感じました。入力層のユニットの数は、データの次元に一致させる必要があるので迷うことはありません。そして出力層のユニットの数も、分類したクラスの数だけ準備するので考える必要はありません。中間層を膨大に増やせば、近似がうまくいくのか調べたいと思います。また、重みやバイアスの設定が難しいとも感じました。

DN15_Jupyter演習2

python
####################################
#      試してみよう           #
####################################
# サンプルとする関数
#yの値を予想するAI
deff(x):y=3*x[0]+2*x[1]returny# 初期設定
definit_network():# print("##### ネットワークの初期化 #####")
network={}nodesNum=10network['W1']=np.random.randn(2,nodesNum)network['W2']=np.random.randn(nodesNum)network['b1']=np.random.randn(nodesNum)network['b2']=np.random.randn()# print_vec("重み1", network['W1'])
# print_vec("重み2", network['W2'])
# print_vec("バイアス1", network['b1'])
# print_vec("バイアス2", network['b2'])
returnnetwork# 順伝播
defforward(network,x):# print("##### 順伝播開始 #####")
W1,W2=network['W1'],network['W2']b1,b2=network['b1'],network['b2']u1=np.dot(x,W1)+b1#z1 = functions.relu(u1)
## 試してみよう
z1=functions.sigmoid(u1)#シグモイドを選択して試す
u2=np.dot(z1,W2)+b2y=u2# print_vec("総入力1", u1)
# print_vec("中間層出力1", z1)
# print_vec("総入力2", u2)
# print_vec("出力1", y)
# print("出力合計: " + str(np.sum(y)))    
returnz1,y# 誤差逆伝播
defbackward(x,d,z1,y):# print("\n##### 誤差逆伝播開始 #####")    
grad={}W1,W2=network['W1'],network['W2']b1,b2=network['b1'],network['b2']# 出力層でのデルタ
delta2=functions.d_mean_squared_error(d,y)# b2の勾配
grad['b2']=np.sum(delta2,axis=0)# W2の勾配
grad['W2']=np.dot(z1.T,delta2)# 中間層でのデルタ
#delta1 = np.dot(delta2, W2.T) * functions.d_relu(z1)
## 試してみよう  #シグモイドを選択して試す
delta1=np.dot(delta2,W2.T)*functions.d_sigmoid(z1)delta1=delta1[np.newaxis,:]# b1の勾配
grad['b1']=np.sum(delta1,axis=0)x=x[np.newaxis,:]# W1の勾配
grad['W1']=np.dot(x.T,delta1)# print_vec("偏微分_重み1", grad["W1"])
# print_vec("偏微分_重み2", grad["W2"])
# print_vec("偏微分_バイアス1", grad["b1"])
# print_vec("偏微分_バイアス2", grad["b2"])
returngrad# サンプルデータを作成
data_sets_size=100000data_sets=[0foriinrange(data_sets_size)]foriinrange(data_sets_size):data_sets[i]={}# ランダムな値を設定
# data_sets[i]['x'] = np.random.rand(2)
## 試してみよう_入力値の設定   # こちらを選択して試す
data_sets[i]['x']=np.random.rand(2)*10-5# -5〜5のランダム数値
# 目標出力を設定
data_sets[i]['d']=f(data_sets[i]['x'])losses=[]# 学習率
learning_rate=0.07# 抽出数
epoch=1000# パラメータの初期化
network=init_network()# データのランダム抽出
random_datasets=np.random.choice(data_sets,epoch)# 勾配降下の繰り返し
fordatasetinrandom_datasets:x,d=dataset['x'],dataset['d']z1,y=forward(network,x)grad=backward(x,d,z1,y)# パラメータに勾配適用
forkeyin('W1','W2','b1','b2'):network[key]-=learning_rate*grad[key]# 誤差
loss=functions.mean_squared_error(d,y)losses.append(loss)print("##### 結果表示 #####")lists=range(epoch)plt.plot(lists,losses,'.')# グラフの表示
plt.show()

スクリーンショット 2019-12-31 6.16.29.png
⇒【考察】
Relu関数からシグモイド関数に変えたことによりグラフの0に近い方の分散が広がった。また、-5〜5のランダム数を選択したことにより<全体的に分散が広がった。選択する関数などにより結果が大きく違う事がわかった。

修了課題

DN16_修了課題(製作課題)

  • (課題)IRISデータを使って、DeepLearninngを作成せよ

設計

 IRISデータを訓練データとテストデータに2:1に分けて学習させて予測するモデルを作成。
+ 入力層:4次元
* 隠れ層:6次元
* 出力層:3次元(3クラス分類問題のため)
* 各層の間の結合:Dense(全結合)
* 入力層→隠れ層の活性化関数:relu
* 隠れ層→出力層の活性化関数:softmax
* 最適化:勾配降下法
* 損失関数:交差エントロピー

スクリーンショット 2020-01-01 16.46.51.png
スクリーンショット 2020-01-01 16.47.10.png

python
importnumpyasnp# ハイパーパラメータ
INPUT_SIZE=4#入力ノードの数
HIDDEN_SIZE=6#中間層(隠れ層)のニューロン数
OUTPUT_SIZE=3#出力層のニューロン数
TRAIN_DATA_SIZE=50# 150個のデータのうちTRAIN_DATA_SIZE個を訓練データとして使用。残りは教師データとして使用。
LEARNING_RATE=0.1# 学習率
EPOCH=1000# 繰り返しの学習回数(エポック数)
# データを読み込み
#
# Iris datasetはこちらか入手。見出しつきで種類ごとに整列されているデータなので、150個のデータを3種類、10件づつに混じるようにCSVデータを準備。
# https://gist.github.com/netj/8836201
x=np.loadtxt('/content/drive/My Drive/DNN_code/data/iris.csv',delimiter=',',skiprows=1,usecols=(0,1,2,3))raw_t=np.loadtxt('/content/drive/My Drive/DNN_code/data/iris.csv',delimiter=',',skiprows=1,dtype="unicode",usecols=(4,))t=np.zeros([150])foriinrange(0,150):vari=raw_t[i]#print(vari,raw_t[i],i)
if("Setosa"invari):t[i]=int(0)elif("Versicolor"invari):t[i]=int(1)elif("Virginica"invari):t[i]=int(2)else:print("エラー",i)#a = [3, 0, 8, 1, 9]
a=t.tolist()a_int=[int(n)fornina]#print(a_int)
#a_one_hot = np.identity(10)[a_int]
a_one_hot=np.identity(len(np.unique(a)))[a_int]#print(a_one_hot)
train_x=x[:TRAIN_DATA_SIZE]train_t=a_one_hot[:TRAIN_DATA_SIZE]test_x=x[TRAIN_DATA_SIZE:]test_t=a_one_hot[TRAIN_DATA_SIZE:]#print("train=",TRAIN_DATA_SIZE,train_x,train_t)
#print("test=",test_x,test_t)
# 重み・バイアス初期化 # Heの初期値(ReLU利用のため)
W1=np.random.randn(INPUT_SIZE,HIDDEN_SIZE)/np.sqrt(INPUT_SIZE)*np.sqrt(2)W2=np.random.randn(HIDDEN_SIZE,OUTPUT_SIZE)/np.sqrt(HIDDEN_SIZE)*np.sqrt(2)# 初期値ゼロから調整
b1=np.zeros(HIDDEN_SIZE)b2=np.zeros(OUTPUT_SIZE)# ReLU関数
defrelu(x):returnnp.maximum(x,0)# ソフトマックス関数
defsoftmax(x):ifx.ndim==2:x=x.Tx=x-np.max(x,axis=0)y=np.exp(x)/np.sum(np.exp(x),axis=0)returny.Tx=x-np.max(x)# オーバーフロー対策
returnnp.exp(x)/np.sum(np.exp(x))# 交差エントロピー誤差
defcross_entropy_error(y,t):ify.shape!=t.shape:raiseValueErrorify.ndim==1:return-(t*np.log(y)).sum()elify.ndim==2:return-(t*np.log(y)).sum()/y.shape[0]else:raiseValueError# 順伝搬
defforward(x):globalW1,W2,b1,b2returnsoftmax(np.dot(relu(np.dot(x,W1)+b1),W2)+b2)# テストデータの結果
test_y=forward(test_x)print("学習前=",(test_y.argmax(axis=1)==test_t.argmax(axis=1)).sum(),'/',150-TRAIN_DATA_SIZE)# 学習ループ
foriinrange(EPOCH):# 順伝搬withデータ保存
y1=np.dot(train_x,W1)+b1y2=relu(y1)train_y=softmax(np.dot(y2,W2)+b2)# 損失関数計算
L=cross_entropy_error(train_y,train_t)ifi%100==0:#100の剰余
print("L=",L)# 勾配計算
a1=(train_y-train_t)/TRAIN_DATA_SIZEb2_gradient=a1.sum(axis=0)W2_gradient=np.dot(y2.T,a1)a2=np.dot(a1,W2.T)a2[y1<=0.0]=0b1_gradient=a2.sum(axis=0)W1_gradient=np.dot(train_x.T,a2)# パラメータ更新
W1=W1-LEARNING_RATE*W1_gradientW2=W2-LEARNING_RATE*W2_gradientb1=b1-LEARNING_RATE*b1_gradientb2=b2-LEARNING_RATE*b2_gradient# 結果表示
# 最終訓練データのL値
L=cross_entropy_error(forward(train_x),train_t)print("最終訓練データのL値=",L)# テストデータの結果
test_y=forward(test_x)print("学習後=",(test_y.argmax(axis=1)==test_t.argmax(axis=1)).sum(),'/',150-TRAIN_DATA_SIZE)

(結果)
学習前= 42 / 100
L= 4.550956552060894
L= 0.3239415165787326
L= 0.2170679838829666
L= 0.04933110713361697
L= 0.0273865499319481
L= 0.018217122389043848
L= 0.013351028977015358
L= 0.010399165844496665
L= 0.008444934117102367
L= 0.007068429052588092
最終訓練データのL値= 0.0060528995955394386
学習後= 89 / 100

⇒【考察】

  • Q1.課題の目的とは?どのような工夫ができそうか
       課題の目的は全体を通したディープラーニングの基本的な仕組みの学習。中間層の数やハイパーパラメータの調整で工夫ができる。
  • Q2.課題を分類タスクで解く場合の意味は何か
       分類タスクの場合には、訓練データとテストデータの生成が学べる。   
  • Q3.IRISデータとは何か2行でのべよ
       機械学習やディープラーニングを学習するために揃えられたデータ。
       3種類のアヤメの分類を題材に4つの特徴量が提供されている。

アクティビティにあらかじめ書かれたソースコード

$
0
0

初学者です。個人的な勉強のために書きました。

アプリ起動時に実行されるメソッド

HelloSampleActivity.java
packagecom.websarva.wings.android.hellosample;importandroid.support.v7.app.AppCompatActivity;importandroid.os.Bundle;publicclassHelloSampleActivityextendsAppCompatActivity{@overrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);//--------------1setcontentView(R.layout.activity_hello_sample);//--2}}

・上記のコードは、あらかじめ記述されているもの

・onCreateメソッドは、Androidアプリが実行されると、まず最初に実行されるメソッドであるため、画面作成やデータの用意など、初期処理として必要なものはこのメソッドに書く必要がある

・①は、親クラスのonCreateメソッドを呼び出し、処理を記述している。Activityクラスは、Activityクラス(またはその子クラス)を継承して作る必要があるため、Activityクラスで定義されているonCreateメソッドをオーバーライドする形で記述する

・②は、このアプリで表示する画面を設定している。上記のコードは、activity_hello_sample.xmlに記述したものを画面として使うので、引数を「R.layout.activity_hello_sample」としている

Rクラス

・Android開発では、resフォルダ内のファイルや、そのファイル中に記述されたリソースは、Androidアプリの管理対象として扱う

・効率よくリソースを管理するために、Androidではそのファイル値を識別するためのint型定数を使用する

・int型定数をまとめたクラスがRクラスで、そこにAndroid studioが自動追記する仕組みになっている。これにより、Rクラス中の定数(R値)を使ってリソースをやり取りできる
 ※R.javaはapp/buikdgenerated/source/r/debug配下のパッケージ内に作成される
 例えば、「R.layout.activity_hello_sample」という記述は、「res/layout/activity_hello_sample.xml」ファイルを示す定数

・Javaでは、定数は大文字で記述することになっているが、R値に関しては、実際のフォルダ階層や、ファイル名などとの関係をはっきりさせるために、記述されたフォルダ名やファイル名をそのまま使っている

pythonを使用したwebサイトの変化監視

$
0
0

あるサイトの変化を監視したいと思い作ってみました。現在は私の自己紹介文を監視していますがurlとclass_nameを変更すると他サイトでも使えます。
20秒毎にページデータを取得し、前回の取得時とデータが異なるかを表示しています。

importrequestsimporttimefrombs4importBeautifulSoupurl="https://qiita.com/sssssssiiiiinnn"class_name='div.newUserPageProfile_info_body.newUserPageProfile_description'file="elems_text.txt"defis_not_changed(old_elem,new_elem):returnold_elem==new_elemdefset_old_elems():try:f=open(file)old_elems=f.read()print(f'{"old_elem":10} : {old_elems}')except:old_elems=''returnold_elemsdefset_new_elems():response=requests.get(url)response.encoding=response.apparent_encodingbs=BeautifulSoup(response.text,'html.parser')new_elems=str(bs.select(class_name))print(f'{"new_elem":10} : {new_elems}')returnnew_elemsdefdisplay_result(old_elem,new_elem):ifnotis_not_changed(old_elems,new_elems):f=open(file,'w')f.writelines(str_elems)f.close()print("Change is detected!!")else:print("not changed...")if__name__=='__main__':try:while(1):print("="*100)new_elems=set_new_elems()old_elems=set_old_elems()display_result(old_elems,new_elems)time.sleep(20)exceptKeyboardInterrupt:print("Interrupted by Ctrl + C")

HTMLとCSS

$
0
0

HTMLとCSSについて学びました。

やっぱり
モノゴトの仕組みを知るのは面白い。
(反面、すぐ理解できないこともありました。。)

HTMLは本体で、CSSはそれを装飾するものらしいです。

日本文だと動詞がメインに使われるので動詞=HTML、
それを装飾する副詞=CSS、みたいなイメージでしょうか。

英文だと名詞=HTML、
形容詞=CSS、になりますね。

プログラミングにも色々な言語があるので、
共通する仕組みや個々の言語の仕組みを徐々に学んでいければより面白そうだなと思っている次第です。

実際のコードを模写してみた結果、CSSの方が長くなっていたのでそれに驚きました。

floatという単語が出てきて、
親要素、子要素が何ちゃら〜、
説明の動画内の概念図では断面の絵が出てきて、

ちょっと何言ってるかわからなかったです!!!

終わり。

音楽ファイル拡張子(DTW向け)

$
0
0

自分用, DTM向け, 備忘録, DAW,VST,VSTi,プラグイン。手元にあるファイルが何なのを軽く調べた。勉強用なので、悪しからず。

拡張子内容
wavWAVE.Microsoft Wave. 44.1kHz,16bit,ステレオはCDと同じ高音質
flacFLAC.Free Lossless Audio Codec. 非可逆圧縮
aiffAIFF.Audio Interchange File Format.
oggOgg Vorbis.MP3よりも聴感上良い音.非可逆圧縮
cafCAF.Core Audio Format.
m4aM4A.Advanced Audio Coding(AAC).カットしやすい.
mp3MP3オーディオ.可逆圧縮.wavの1/10程度の容量.汎用性が高い.
midiMID.MIDI.楽器の演奏情報を記録したデータ
songStudio One Song
soundsetStudio One Soundset.
peakAdobe Peak Audio File
cprCubase Project
componentCubaseのコンポーネント.AU.
dllAUとして
SFSF2.SoundFontオーディオ.ソフト音源
SFZ
.sfArkソフト音源圧縮ファイル.sfark等で解凍
sfpackソフト音源圧縮ファイル.sfpack等で解凍
vstvst3.Steinberg's Virtual Studio Technology.VSTプラグイン.
vstsoundSteinberg VST Sound archive.
alsAbleton Live Set
advAbleton device preset
agrAbleton groove file
alcAbleton live clip
alpAbleton live pack
amsAbleton meta sound
amxdAbleton max for Live device
asdAbleton warp analysis file
askAbleton skin file
用語意味
AUAudio Unit.
BPMBeats Per Minute.1分間あたりの拍節数.「テンポ」の単位.♩=60=BPM
VSTiVST Instruments.

参考

[1] Live specific file types (.adg / .als / .alp / ...)


Railsチュートリアル 第13章 ユーザーのマイクロポスト - 画像アップローダーのテストに存在する一つの不具合と、その解消策

$
0
0

画像アップローダーのテスト(オリジナル)

Railsチュートリアル本文においては、第13章の演習 - 基本的な画像アップロードに登場するテストです。

同演習でFILL_INとなっている箇所を埋めると、テストの内容は以下のようになります。

test/integration/microposts_interface_test.rb
require'test_helper'classMicropostsInterfaceTest<ActionDispatch::IntegrationTestdefsetup@user=users(:rhakurei)@other_user=users(:skomeiji)endtest"micropost interface"dolog_in_as(@user)getroot_pathassert_select'img.gravatar'assert_select'h1',@user.nameassert_select'span',/#{@user.microposts.count}/assert_select'form[action="/microposts"]'assert_select'textarea'assert_select'div.pagination'assert_select'input[type="file"]'# 無効な送信assert_no_difference'Micropost.count'dopostmicroposts_path,params: {micropost: {content: ""}}endassert_select'div#error_explanation'# 有効な送信content="This micropost really ties the room together"picture=fixture_file_upload('test/fixtures/lgtm3.png','image/png')assert_difference'Micropost.count',1dopostmicroposts_path,params: {micropost: {content: content,picture: picture}}endassertassigns(:micropost).picture?assert_redirected_toroot_urlfollow_redirect!assert_matchcontent,response.body# 投稿を削除するassert_select'a',text: 'delete'first_micropost=@user.microposts.paginate(page: 1).firstassert_difference'Micropost.count',-1dodeletemicropost_path(first_micropost)end# 違うユーザーのプロフィールにアクセス(削除リンクがないことの確認)getuser_path(users(:mkirisame))assert_select'a',text: 'delete',count: 0end# ...略end

このテストに関する一つの不具合

実は、上記のテストには一つ不具合があります。

例えば、以下のようにapp/views/microposts/_micropost.html.erbから画像表示部分の実装を取り除くと、テストの結果はどうなるでしょうか。

app/views/microposts/_micropost.html.erb
<li id="micropost-<%= micropost.id %>">
    <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
    <span class="user"><%= link_to micropost.user.name, micropost.user %></span>
    <span class="content">
      <%= micropost.content %>
-     <%= image_tag micropost.picture.url if micropost.picture? %>
</span>
    <span class="timestamp">
      Posted <%= time_ago_in_words(micropost.created_at) %> ago.
      <% if current_user?(micropost.user) %>
        <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %>
      <% end %>
    </span>
  </li>

以下のようにテストが成功してしまうのです。

# rails test test/integration/microposts_interface_test.rb
Running via Spring preloader in process 15428
Started with run options --seed 30155

  2/2: [===================================] 100% Time: 00:00:04, Time: 00:00:04

Finished in 4.32782s
2 tests, 23 assertions, 0 failures, 0 errors, 0 skips

「画像を投稿したのに、投稿した画像がフィードに表示されていない」というのは、テストで検出できるべきバグであり、それを検出できないのはテストの不具合です。早速、テストに存在する当該不具合を解消していきましょう。

画像アップローダーのテストに存在する不具合を解消する

test/integration/microposts_interface_test.rbを以下のように変更するのが一つの方法です(他にも方法はあるかもしれません)。

test/integration/microposts_interface_test.rb
  require 'test_helper'

  class MicropostsInterfaceTest < ActionDispatch::IntegrationTest
    def setup
      @user = users(:rhakurei)
      @other_user = users(:skomeiji)
    end

    test "micropost interface" do
      log_in_as(@user)
      get root_path
      ...略
      # 有効な送信
      content = "This micropost really ties the room together"
      picture = fixture_file_upload('test/fixtures/lgtm3.png', 'image/png')
      assert_difference 'Micropost.count', 1 do
        post microposts_path, params: { micropost: { content: content, picture: picture } }
      end
-     assert assigns(:micropost).picture?
      assert_redirected_to root_url
      follow_redirect!
      assert_match content, response.body
+     assert_select "img[src*='#{picture.original_filename}']"
      # 投稿を削除する
      ...略
    end

    ...略
  end

新たなテストのポイント

ポイントは以下のassert_selectです。

assert_select"img[src*='#{picture.original_filename}']"

picture.original_filenameというのは、「アップロードしたファイルのローカルにおけるファイル名」と考えてかまいません1。また、CSSセレクタで部分一致検索を行うためには、*=という演算子を用います。

結果、上記assert_selectは、「src属性に、アップロードしたファイルのローカルにおけるファイル名を含むimg要素が存在すること」をチェックします。

また、Rails5で非推奨とされているassignsを使わない形となり、Webアプリケーションのテストの書き方としてより望ましいとされる「Request Specなテストの書き方」に近づけることができます。

実装を変更したテストが、本当に正しい対象へのテストなのか

マイクロポストに関連付けられた画像を表示する部分が欠落したビューに対してテストを実行する

app/views/microposts/_micropost.html.erbの内容が以下のようになっている場合、テストの結果はどうなるでしょうか。

app/views/microposts/_micropost.html.erb(不具合あり)
<liid="micropost-<%=micropost.id%>"><%=link_togravatar_for(micropost.user,size: 50),micropost.user%><spanclass="user"><%=link_tomicropost.user.name,micropost.user%></span><spanclass="content"><%=micropost.content%></span><spanclass="timestamp">
    Posted <%=time_ago_in_words(micropost.created_at)%> ago.
    <%ifcurrent_user?(micropost.user)%><%=link_to"delete",micropost,method: :delete,data: {confirm: "You sure?"}%><%end%></span></li>
# rails test test/integration/microposts_interface_test.rb
Running via Spring preloader in process 15608
Started with run options --seed 24115

 FAIL["test_micropost_interface", MicropostsInterfaceTest, 4.238321199998609]
 test_micropost_interface#MicropostsInterfaceTest (4.24s)
        Expected at least 1 element matching "img[src*='lgtm3.png']", found 0..
        Expected 0 to be >= 1.
        test/integration/microposts_interface_test.rb:34:in `block in <class:MicropostsInterfaceTest>'

  2/2: [===================================] 100% Time: 00:00:04, Time: 00:00:04

Finished in 4.51704s
2 tests, 20 assertions, 1 failures, 0 errors, 0 skips
Expected at least 1 element matching "img[src*='lgtm3.png']", found 0..
Expected 0 to be >= 1.
test/integration/microposts_interface_test.rb:34

以上のようなメッセージが出てテストが失敗しています。「lgtm3.pngという文字列を含むsrc属性を持つimg要素が、1つ以上なければならないのに、1つも存在しない」という趣旨のメッセージですね。

私の環境では、test/integration/microposts_interface_test.rbの34行目は以下内容になっています。

test/integration/microposts_interface_test.rb(34行目)
assert_select"img[src*='#{picture.original_filename}']"

確かに想定通りの形でテストが失敗しているといえます。

マイクロポストに関連付けられた画像を表示する部分を正しく実装したビューに対してテストを実行する

app/views/microposts/_micropost.html.erbの中身を、今度は以下のようにしてテストを実行してみましょう。

app/views/microposts/_micropost.html.erb(不具合修正後)
<liid="micropost-<%=micropost.id%>"><%=link_togravatar_for(micropost.user,size: 50),micropost.user%><spanclass="user"><%=link_tomicropost.user.name,micropost.user%></span><spanclass="content"><%=micropost.content%><%=image_tagmicropost.picture.urlifmicropost.picture?%></span><spanclass="timestamp">
    Posted <%=time_ago_in_words(micropost.created_at)%> ago.
    <%ifcurrent_user?(micropost.user)%><%=link_to"delete",micropost,method: :delete,data: {confirm: "You sure?"}%><%end%></span></li>
# rails test test/integration/microposts_interface_test.rb
Running via Spring preloader in process 15621
Started with run options --seed 58972

  2/2: [===================================] 100% Time: 00:00:04, Time: 00:00:04

Finished in 4.61052s
2 tests, 23 assertions, 0 failures, 0 errors, 0 skips

今度こそテストが無事成功しました。

関連リンク

「CSSにおける部分一致検索」については、以下の記事を参考にさせていただきました。ありがとうございます。


  1. より厳密には、「CarrierWaveデフォルトの状態だと日本語の文字が"__"に置き換えられてしまう」等の制限があるようなのですが、本記事で扱う内容の範囲外となるため、そのあたりの説明は割愛します。 

余談。

初心者エンジニアが今日使ったLinuxコマンドまとめてみた~その1~

$
0
0

これが2回目の投稿となります。
私の投稿ではその日学んだことをアウトプットすることをメインとしております。
表現が適切でない場合や、間違いがあればコメントにてご指摘いただけると嬉しいです。
よろしくお願いいたします。

今日使ったLinuxコマンドまとめ

hostname
→ユーザーのホストネームを確認するときに使用するコマンド

name -m
→ビット数を確認するときに使用するコマンド

less [ファイル名]
→ファイルの中身を確認

id ユーザー名
→ユーザーをスイッチさせずに、id・主グループを確認できるコマンド

ss -ant
→ポートが上がってるかを確認したいときに使うコマンド。
※出力されたポートナンバーが現在上がってるポート

cd [ディレクトリ]
→ディレクトリを移動するときに使うコマンド

ls
→ディレクトリ内を確認するときに使用するコマンド

初心者がLaravelをインストールしてみた!

$
0
0

前回にて下調べを行ったLaravelを、早速インストールしてみました!

スペック

OS:Windows10 Home 64bit
xampp Version: 7.3.9
Composer version:1.8.6

xamppとComposerのインストール

Laravelは公式サイトからダウンロードしたりするのではなく、Composerにコマンドを打ち込んでインストールします。
その為、Laravelを使うにはxamppとComposerがインストールされている必要があります。
私はLaravelを使い始める前に既にインストールした為、説明は割愛させていただきます。
こちらの記事を読んで下さった方でまだxamppとComposerをインストールされていない方は、下記の公式サイトからダウンロードして下さい。

xampp:https://www.apachefriends.org/jp/index.html

Composer:https://getcomposer.org/

Composerでインストールのコマンドを入力

コマンドプロンプトを立ち上げ、Laravelのプロジェクトを格納させたい場所に移動したら、以下のコマンドを入力します。
composer create-project laravel/laravel --prefer-dist プロジェクト名
コマンドを打ち込むとインストールが開始されますが、完了までに5~10分程かかります。
気長に待ちましょう。
以下の画面になりましたら、インストール完了です。
Laravel install 02 (2).PNG

フォルダも以下のようになっています。
lara フォルダ.PNG

動作確認

早速インストールしたLaravelプロジェクトがきちんと動くかテストを行いました。
作成されたディレクトリに移動し、以下のコマンドでビルドインサーバーを立ち上げます。
php artisan serve

又、ローカルホストを立ち上げる場合はこちらのコマンドを入力します。
php -S localhost:8000 -t public

画面にLaravel development server started: http://127.0.0.1:8000とメッセージが表れましたら、サーバーが正常に立ち上がります。
ブラウザを立ち上げ、http://localhost:8000にアクセスします。
すると、以下の画面が表れます!
これでLaravelの環境構築は完了です!
Laravel install 05 (2).png

Hello Worldしてみた

新環境構築の定番である「Hello World」もしっかり行いました。
プロジェクト名/resources/views内にある「welcome_blade.php」というファイルを開きます。
これは、ローカルホストで開いた際に初めに表れる画面プログラムファイルとなっています。
hello world Lara.PNG
上図の赤枠部分がデフォルトだと「Laravel」となっていますが、これを「Hello World!」にします。
保存し、ブラウザで再びhttp://localhost:8000にアクセスすると、「Laravel」の部分が「Hello World!」になっていることが確認出来ます。
helloLara6.PNG

まとめ

LaravelはPHPの開発環境が整っていれば、意外とすぐにできました。
少し触ってみましたが、PHPを理解していればかなり便利なツールになれますね。
しかし、仕組みを理解するとなると、オブジェクト指向の知識も多少必要だと感じた為、こちらも併せて勉強していきたいと思います。
Laravelを活用して、色々作成してみます。

参考文献

RAKUS Developers Blog | ラクス エンジニアブログ 失敗しない Laravel 導入方法
http://tech-blog.rakus.co.jp/entry/2017/11/16/110742

侍エンジニアブログ Laravelをインストールしよう!導入手順まとめ(Mac, Windows)
https://www.sejuku.net/blog/106106

学習記録 その19(23日目)

$
0
0

学習記録(23日目)

勉強開始:12/7(土)〜

教材等:
・大重美幸『詳細! Python3 入門ノート』(ソーテック社、2017年):12/19(木)読了
・Progate Python講座(全5コース):12/21(土)終了
・Andreas C. Müller、Sarah Guido『(邦題)Pythonではじめる機械学習』(オライリージャパン、2017年):12月23日(土)読了
Kaggle : Real or Not? NLP with Disaster Tweets:12月28日(土)投稿〜1月3日(金)まで調整
Wes Mckinney『(邦題)Pythonによるデータ分析入門』(オライリージャパン、2018年):1月4日(土)〜

『Pythonによるデータ分析入門』

p.276 8章 データラングリング まで読み終わり。

6章 データの読み込み、書き出しとファイル形式

・pandasの特徴はテーブル形式データをデータフレームオブジェクトとして読み込む関数が豊富なこと。
 read_csv、read_table、read_excel、read_html ...
 読み込み関数のいくつかでは自動的に型推論が行われるため、必ずしも細部を設定する必要はない。
 デフォルトの区切り文字(sep) : read_csv→カンマ、read_table→\t(水平タブ)
 他のものを区切りとする場合は引数で指定する。

・一部の行の形式が異なるようなファイルのデータフレーム化
 csf.readerに渡す。帰ってきたタプルをlinesで読み込む。ヘッダーとデータ行に分割
 ディクショナリ内包表記とzip(*values)でディクショナリ形式に ...

・json(JavaScript Object Notation)
 Webブラウザとアプリケーション間においてHTTPリクエストでデータをやりとりする際の形式の1つ。

・HTML/XML形式のデータ読み書きも可能。
 read関数で読み込み、skipやindexを付けてディクショナリ化し、最後にデータフレーム化する。
 いわゆるスクレイピングという作業。データの形を整えて使えるようにする。
 Kaggleなどは整っているデータが多いのでやらない? むしろ実務で多く使いそうな技術。

・HDF5 科学的な配列データを保存するためのファイル形式。
 Cで書かれており、効率よくデータを読み書きできるので、巨大なデータセットを使うのによい選択。

・excelも読み込める。sqlデータベースからも読み込める。

7章 データのクリーニングと前処理

・欠損値の取り扱い
 dropnaで欠損値(NA, NaN)を含む行を丸ごと落とす。fillnaで埋める。前後に準ずるffillやbfillもある。
 引数にhow='all'を指定で、全てがNAの行のみ落とすこともできる。列は他と同じでaxis=1を指定。
 fillnaにディクショナリを与えると、列ごとに異なる数値で埋めることができる。inplaceは上書き。
 fillnaにdata.meanを与えると、算術平均で穴埋めもできる。

・データ変形
 duplicateで真偽値のシリーズを戻す。drop_duplicatesは真偽値がtrue(他と同じ要素)のみ削除
 mapで要素ごとの変換。ディクショナリも渡せる。(どの関数も共通してディクショナリ渡せそう。)
 replaceでもできる。kaggleでよく見るのはこっちな気がする。第1引数を第2の数値に変える。

・離散化とビニング
 リストで要素を作り、pandasのcutに引数として渡すことでビンに分けられる。

・外れ値の検出
 data[(np.abs(data) > 3).any(1)、3以上というのは例。
 指定した数値よりもdata要素の絶対値が大きいものが1つでもある(any)ものをリストアップする。
 = np.sign(data)*3 とすれば、各要素の符号に応じた数値を返すsignと組み合わせて上限を作れる。

・ランダムサンプリング
 random.permutation(5)で5つのランダムを、takeで同等のサンプリングを行える。
 非復元抽出を選択するにはsampleメソッドにreplace = Trueを渡す。

・標識変数の取り出し。リスト、for分、extend(x.split('|'))で|を基準に分割したデータをリストに入れる。
 pandasのuniqueで取り出すと、構成する各要素のリストが作れる。p229
 splitもkaggleでよく使ってた。

・正規表現。reモジュールを使用、complile、findall、regex.match ...

8章 データラングリング

・階層型インデックス。2つ以上のインデックスを持つデータ。
 aというインデックスに1,2,3の要素、bというインデックスに1,2,3の要素。など。
 unstackとstackでピボットできる。(内側の要素をcolumnsラベルとして使うなど)

・階層の順序変更はswaplevelでできる。sort_indexで並び替え。
 levelを引数に渡すと、その階層を使うか指定。外側から0、1、...

・データフレームの列をインデックスにできる。set.index
 set.index('a')とすれば、aの列を構成する要素がindexとして新たに加わる。
 reset.indexはこの逆動作である。

・結合とマージ、concat、merge、でくっつける。基本的に内部結合(innner)で指定されており、共通なもののみ結果に含めるようになっている。独立であるものも、全てを結果に含めるのであればhow='outer'を指定する。

・stackは欠損値を除去するようになっているが、dropna=Falseで落とさないこともできる。
 これに限らず、引数で指定することでだいたいの操作はできそう(と判断。)
 もししたい操作があれば、まず引数を調べるとよいかもしれない。

Viewing all 21599 articles
Browse latest View live