強まっていこう

あっちゃこっちゃへ強まっていくためのブログです。

ディープラーニングで実際簡単なものを学習させてみる

wolfbash.hateblo.jp

上の記事では、学習なしで AND回路を作ってみました。今回は前回のコードに対して学習のコードを加えます。

#!/usr/bin/env python

import os
import numpy as np

class NeuralNetwork():

  saveFile = 'train.npy'

  def __init__(self, inSize, outSize, hidSize):
    if os.path.isfile(NeuralNetwork.saveFile):
      w = np.load(NeuralNetwork.saveFile)
      self.w1 = w[0]
      self.w2 = w[1]
    else:
      self.w1 = np.random.randn(inSize, hidSize)
      self.w2 = np.random.randn(hidSize, outSize)

  def forward(self, x):
    self.z = np.dot(x, self.w1)
    self.z2 = self.sigmoid(self.z)
    self.z3 = np.dot(self.z2, self.w2)
    return self.sigmoid(self.z3)

  def backward(self, data, result, check):
    delta = (result - check) * self.sigmoidPrime(check)
    error = delta.dot(self.w2.T)
    delta2 = error * self.sigmoidPrime(self.z2)
    self.w1 += data.T.dot(delta2)
    self.w2 += self.z2.T.dot(delta)

  def train(self, data, result):
    self.backward(data, result, self.forward(data))

  def save(self):
    np.save(NeuralNetwork.saveFile, np.array([ self.w1, self.w2 ]))

  def predict(self, x):
    print("""
[Prediction]
Data: {}
Result: {}
    """.format(x, self.forward(x)))

  def sigmoid(self, x): return 1 / (1 + np.exp(-x))

  def sigmoidPrime(self, x): return x * (1 - x)

if __name__ == '__main__':
  sample = np.array(([ 0, 0 ], [ 0, 1 ], [ 1, 0 ], [ 1, 1 ]))
  sampleResult = np.array(([ 0 ], [ 1 ], [ 1 ], [ 1 ]))

  nn = NeuralNetwork(2, 1, 3)
  for i in range(1000):
    print("""
# {}
Data: {}
Result: {}
Prediction: {}
Diff: {}
    """.format(i, sample, sampleResult, nn.forward(sample), np.mean(np.square(sampleResult - nn.forward(sample)))))
    nn.train(sample, sampleResult)
  nn.save()

  challenge = np.array([ 1, 1 ])
  nn.predict(challenge)

このコードでは、学習が終了次第 train.npy に対して学習結果を保存します。
np は save と load の便利なメソッドを持っているのでそれを利用して、学習結果である重みを保存しています。
一度学習したら次回はそのセーブデータからデータをロードして初期値として使います。叩けば叩くほどどんどん賢くなっていくと言うわけです。

前回の NeuralNetwork と比べ増えているメソッドとして、backward、train、save、predict、sigmoidPrime があります。

forward から学習結果が吐き出されそれを、backward に叩き込み、実際の正解を比べてみて、重みを微調整して行きます。

(この例ではかなり簡易化しているのですが、通常は forward の処理が何個もあるので、backward の処理は forward と逆の順番で次々と処理を流していくことになります。)

backwardの詳しい処理に関しては数学の偏微分、全微分あたりがもりもり出てくるので、追わない方が良いです。幸せになれません。
sigmoidPrime をかましてふんふんすると良い感じになるんだな、ぐらい思っておいて OK です。ディープラーニングで大事なのって数学の知識ではないので。
そこいらは、数学好きな変態達が便利なものを作ってくれるのでそれを使うだけで良い、ぐらいに思っておいてください。

エフェクターの作りは知らんが、そいつらを使って音は作れる、そんなノリがマジで大事ですんで。そうしないと心がブチ折られ続けます。

世のドキュメントはまじで数学知識を要求しすぎですって。普通に使う分には要らないでしょ・・・。
実は簡単すぎるからってそこで敷居を上げたがっているとしか思えない。

で、結局深いことする時は数学知識がトップランクの連中がよってたかっても解らず、なんとなくいろいろ数値いじって関数かまして、なんとなくうまく行ったヨ!とかやってんでしょ?
秘伝のレシピを作るノリで。じゃぁ最初からなんとなくうまく行ったよ!をみんなにやらせるべきだと思いますわ。

今回こそボヤくまい、と思ったのに結局ボヤくと言うね。

話戻します。

train は実際の学習処理になります。サンプルデータとその回答データを食わせて学習させます。

学習は、1000 回ループで回しています。やればやるほど正解率が上がっていきますが、物によってはやりすぎも良くなかったりします。過学習とか言う状態です。そういう話もまたおいおい。

学習させた NeuralNetwork に値を与えて予想させるのが、predict になります。

ある程度学習を回した回路に 1, 1 を与えると

[Prediction]
Data: [1 1]
Result: [0.98882596]

が返ってきます。0.98 ですが、まぁ 1 に近い値が出てますね。なんじゃこのポンコツマシーンはと思いましたか?こんなもんなんす。

で、これは回帰って言います。ディープラーニングには複数種類があります。回帰は株価予想や業績予想など任意のデータから結果の数字を予想するものです。
一方分類ってのがあります。これは、グループ分けになります。その他諸々ありますが、まぁそんなのもおいおい。

次回は、今回みたいな糞の役にも立たないポンコツマシーンではなくて、もうちょっとマシな代物を作って行きます。

ディープラーニングは難しすぎ、とほっぽり出したプログラマへの助け舟

ディープラーニング、気軽な気持ちで調べてみるも「なんじゃこりゃ!」と撤退。ありますよね。

何がニューロンだ、何がシナプスだ、何がニューラルネットワークだ!うざいんじゃボケェ!!

こっちはなぁ、脳みその仕組みを知りたいわけじゃねぇんだよハゲが!!と思うでしょ?

そもそもね、インターネッツなウェッブサイツを作ろうとしているのに、さぁどうやってネットワークカードが通信しているか、その理論からお教えしましょう! なんてことを言っているのと同レベルのドキュメントばかりでうんざりなんですわ。

変な数式なんてこっちは知ったこっちゃ無い。道具の成り立ちなんて知るかよと。その使い方だけ教えろこのポンスケが、ときたもんです。

こんなの読んでね、プログラマに理解しろっつー方が無理ですよ。そんなに暇じゃないんでイラッイラします。

パーセプトロンだかパンシロンだか、デストロンだか知りませんが、変な丸と線を書いてキャッキャ喜んでんじゃねぇよ、と。何故に猫も杓子もすでにどこそこにあるようなものと同じものを書くんでしょう。自分が書いたらもっとわかりやすい絵になるとでも思ってんですかね。

なので、今回はプログラマ視点でこいつの倒し方のコツを伝えます。突破口を開くきっかけになれば、と思いますね。プログラマはね、コードが真っ先に来ないと理解出来ないもんなんですわ。

と言うわけで、はいコード。

#!/usr/bin/env python

import numpy as np

class NeuralNetwork():

  def __init__(self, inSize, outSize, hidSize):
    self.w1 = np.random.randn(inSize, hidSize)
    self.w2 = np.random.randn(hidSize, outSize)

  def forward(self, x):
    self.z = np.dot(x, self.w1)
    self.z2 = self.sigmoid(self.z)
    self.z3 = np.dot(self.z2, self.w2)
    return self.sigmoid(self.z3)

  def sigmoid(self, x): return 1 / (1 + np.exp(-x))

if __name__ == '__main__':
  sample = np.array(([ 0, 0 ], [ 0, 1 ], [ 1, 0 ], [ 1, 1 ]))
  sampleResult = np.array(([ 0 ], [ 1 ], [ 1 ], [ 1 ]))

  nn = NeuralNetwork(2, 1, 3)

  print("Prediction: \n" + str(nn.forward(sample)))
  print("Correct: \n" + str(sampleResult))
続きを読む

gulp で PHP + twig + pug + SCSS あたりで快適にコード書きつつ js、css を min 化するそんな素敵ライフを送る方法

UI のプロトタイプとかちゃちゃっと書きたい時に pug で書いてたりはしたんだけど、pug ばっか書いてすっかり中毒になると、もう素の HTML で twig なんて書いてらんない体に。
pug を twig に変換するやつを書いてくれてる人もいて試しちゃみたけど、どうもイマイチ。ふと思った。pug の | 使って twig を pug 側に書いちまえばええんでねぇの。

こげな感じで。

doctype html
html(lang="ja")
  head
    meta(charset="utf-8")
    meta(http-equiv="X-UA-Compatible" content="IE=edge")
    meta(name="viewport" content="width=device-width, initial-scale=1")
    |{% block meta %}{% endblock %}
    link(href!="{{ siteUrl('css/main.min.css') }}" rel="stylesheet")
    link(href!="{{ siteUrl('fa/css/fontawesome-all.min.css') }}" rel="stylesheet")
    |{% block head %}{% endblock %}
  body
    script(src!="{{ siteUrl('js/jquery.min.js') }}")

for だの if だのも全て | 使って書いちゃえばイケる。快適ライフ過ぎてあっという間に1つアプリを作った。そのうち紹介したりしなかったりするかもしらん。

機嫌が良いので gulpfile.js を公開しようそうしよう。パスはこんな感じを想定。** はディレクトリ階層問わずってこと。

続きを読む

毎度忘れる正規表現代表格 肯定否定先読み後読みの覚え方のコツ

毎回忘れてググる人多いでしょ?まぁ覚える必要も無いんですが、簡単に覚えられるので自分なりのコツを。

後ろにその文字が無いとダメ、あったらダメ
前にその文字が無いとダメ、あったらダメ

この4パターンがあるわけですが

何かしらの文字(?=無いとダメ)

(?<=無いとダメ)何かしらの文字

まずこの2つを覚えましょう。

(?=) は後ろ側にその文字が無いとダメなことを表しています。

(?<=) は前側にその文字が無いとダメなことを表しています。

?= の間に < を入れて前に押しやる(シフトする)イメージで覚えておくと良いです。

これらの = を ! に変えると、あったらダメに変化します。

何かしらの文字(?!あったらダメ)

(?<!あったらダメ)何かしらの文字

こうやって覚えるといくぶん覚えやすいんじゃないでしょうか。

実はすごく大したことない代物なんですが、日本語名がいかつすぎるのと記号がいまいちなので覚えづらく感じるんだと思います。

続きを読む

PHP、JS、Sass 編集でブラウザを自動更新しつつ CSS、JS を min 化して幸せになっときたい諸氏へ

大概の FW 使ってると、public 以下が公開用ファイル達のいるドキュメントルートで、その上に PHP のファイルなどが居る的な感じになっているはず。

controllers/*.php
models/*.php
sass/*.scss
js/*.js
public/css/*.min.css
public/js/*.min.js
public/index.php

要するにこんな感じになってんじゃないかと思うわけ。

そいだら、js や scss のディレクトリ配下のファイルいじったら勝手に public 以下に min が作られてリロードされると楽だと思うわけ。

php もいじったら勝手にリロードされたら楽だと思うわけ。

そんな gulpfile.js なわけ。

npm i gulp@3.9.1 gulp-connect-php gulp-plumber gulp-sass gulp-uglify gulp-clean-css gulp-rename browser-sync --save-dev
var conf = {
  ip: '0.0.0.0',
  port: 8080,
  uiPort: 8081,
  phpPort: 8082,
  documentRoot: './public'
};

var gulp = require('gulp');
var connectPHP = require('gulp-connect-php');
var plumber = require('gulp-plumber');
var pug = require('gulp-pug');
var sass = require('gulp-sass');
var uglify = require('gulp-uglify');
var cleanCSS = require('gulp-clean-css');
var rename = require('gulp-rename');
var browserSync = require('browser-sync').create();

gulp.task('server', () => {
  connectPHP.server({
    port: conf.phpPort,
    hostname: conf.ip,
    base: conf.documentRoot,
  }, () => {
    browserSync.init({
      proxy: 'localhost:' + conf.phpPort,
      port: conf.port,
      ui: { port: conf.uiPort }
    });
  });
});

gulp.task('php', [ 'server' ], () => {
  gulp.watch([ '**/*.php' ], () => {
    gulp.src([ '**/*.php', '!vendor/**/*.php', '!node_modules/**/*.php' ])
      .pipe(plumber())
      .pipe(browserSync.reload({ stream: true }));
  });
});

gulp.task('js', [ 'server' ], () => {
  gulp.watch([ 'js/**/*.js' ], () => {
    gulp.src('js/**/*.js')
      .pipe(plumber())
      .pipe(uglify())
      .pipe(rename({ extname: '.min.js' }))
      .pipe(gulp.dest(conf.documentRoot + '/js/'))
      .pipe(browserSync.reload({ stream: true }));
  });
});

gulp.task('scss', [ 'server' ], () => {
  gulp.watch([ 'sass/**/*.scss' ], () => {
    gulp.src('sass/**/*.scss')
      .pipe(plumber())
      .pipe(sass({ outputStyle: 'expanded' }))
      .pipe(cleanCSS())
      .pipe(rename({ extname: '.min.css' }))
      .pipe(gulp.dest(conf.documentRoot + '/css/'))
      .pipe(browserSync.reload({ stream: true }));
  });
});

gulp.task('watch', [ 'php', 'js', 'scss' ]);

gulp.task('default', [ 'watch' ]);

gulp ひっぱたいて 8080 にアクセスすると幸せになるわけ。PHP 側から js や css は min を指定しておくと幸せなわけ。

ファイルが増えまくってリロードが遅くなってきたら、いじるファイルタイプだけを監視すれば良いわけ。

gulp php js

後はノリ。

HTML、JS、Sass 編集でブラウザー自動更新、そして、CSS、JS を min 化、そんな gulpfile.js は無いかとお困りの貴殿へ

どうやりゃ良いんですか?って聞かれたので。確かにまとまってるところが無いっぽい。

よくやるパターンだと思うけどなぁーーーと思ったので貼り付ける。

npm i gulp@3.9.1 gulp-plumber gulp-sass gulp-uglify gulp-clean-css gulp-rename browser-sync --save-dev
var conf = {
  port: 8080,
  uiPort: 8081
};

var gulp = require('gulp');
var plumber = require('gulp-plumber');
var sass = require('gulp-sass');
var uglify = require('gulp-uglify');
var cleanCSS = require('gulp-clean-css');
var rename = require('gulp-rename');
var browserSync = require('browser-sync').create();

gulp.task('uglify', () => {
  gulp.src([ 'js/**/*.js', '!js/**/*.min.js' ])
    .pipe(uglify())
    .pipe(rename({ extname: '.min.js' }))
    .pipe(gulp.dest('js/'));
});

gulp.task('cleanCSS',() => {
  gulp.src([ 'css/**/*.css', '!css/**/*.min.css' ])
    .pipe(cleanCSS())
    .pipe(rename({ extname: '.min.js' }))
    .pipe(gulp.dest('css/'));
});

gulp.task('minify', [ 'uglify', 'cleanCSS' ]);

gulp.task('browserSync', () => {
  browserSync.init({
    port: conf.port,
    ui: { port: conf.uiPort },
    server: './'
  });
});

gulp.task('watch-html', [ 'browserSync' ], () => {
  gulp.watch([ '**/*.html' ], () => {
    gulp.src('**/*.html')
      .pipe(browserSync.reload({ stream: true }));
  });
});

gulp.task('watch-js', [ 'browserSync' ], () => {
  gulp.watch([ 'js/**/*.js' ], () => {
    gulp.src('js/**/*.js')
      .pipe(browserSync.reload({ stream: true }));
  });
});

gulp.task('watch-sass', [ 'browserSync' ], () => {
  gulp.watch([ 'sass/**/*.sass' ], () => {
    gulp.src('sass/**/*.sass')
      .pipe(plumber())
      .pipe(sass({ outputStyle: 'expanded' }))
      .pipe(gulp.dest('./css/'))
      .pipe(browserSync.reload({ stream: true }));
  });
});

gulp.task('watch-scss', [ 'browserSync' ], () => {
  gulp.watch([ 'sass/**/*.scss' ], () => {
    gulp.src('sass/**/*.scss')
      .pipe(plumber())
      .pipe(sass({ outputStyle: 'expanded' }))
      .pipe(gulp.dest('./css/'))
      .pipe(browserSync.reload({ stream: true }));
  });
});

gulp.task('watch', [ 'watch-html', 'watch-js', 'watch-sass', 'watch-scss' ]);

gulp.task('default', [ 'watch' ]);
gulp

で、ポート 8080 で browserSync のサーバが Listen。

index.html
js/*.js
sass/*.sass
sass/*.scss

こんなディレクトリ構造の HTML、JS、Sass のファイルを弄るとブラウザをリロード。
Sass のファイルは css/ に .css として作成される。
それぞれディレクトリは深さ問わず。

全部監視させるとリロードが遅くなる場合、監視対象を絞れば良し。JS だけ監視するなら

gulp watch-js

HTML と Sass だけなら

gulp watch-html watch-sass
gulp minify

とやりゃ、js/、css/ 内に min が作成される。

後はノリとグルーヴ感を大切にすれば OK。

メルカリで出品してみたいけどよくわからない初心者の不安を払拭するための記事 - メルカリのススメ

家にいらない物があるからメルカリで売りたいなぁ。でもよくわからんし、面倒くさそうだから良いやぁ。

そんな人って多いと思います。そう言う人達の背中を押すための記事になればと思い書いてみます。

メルカリはなにげに高値で物が売れます。

自分は仕事柄、技術書籍を多く出品しているのですが、書き込みや折れ目などがなければ、買った値段の半値程度で売れたりします。

3,400円のものが 3,000円で売れたりもしました。アマゾンのリコマースでは1,000円と評価された品です。ブックオフだと更に酷い評価額になります。

嫁のブランド物は質屋で 1,000円で買い取りになると言われたものが 14,000円で売れたりしましたし。

ただ売れたお金から手数用としてメルカリに 10% 取られはしますけども。

(手数料なしの楽天ラクマってのもあるんですが人が少ないせいかあまり売れません。もうちょっと流行ってくれると良いんですがね・・・。)

3,000円で売れたら自分に入るお金は 2,700円です。基本、送料込みでの出品にすべきなのでここからさらに送料が引かれます。

それでも随分と街の中古屋に売るよりは手元にお金が入ってくるので是非活用すべきだと思うんですが、恐らく大半の人が億劫になる部分。それが配送だと思います。

どうやって送りゃ良いのかわからん!いくらかかるのかもわからん!これが一番のボトルネックでしょう。実際、自分も嫁も嫁の周りもそうでしたからね。間違いないと思います。

なのでそこを説明します。

送る方法として郵便局とヤマトがあります。ヤマトであればヤマトに取りに来てもらう(30円かかる)か、ファミマから送ることが出来ます(ヤマト営業所持ち込みも出来ますが近場にないと思います)。

ヤマトに集荷を頼むのは頼むのも待つのも面倒なのでよっぽど大きい商品以外はコンビニ持ち込みの方が良いと思います。実際自分はコンビニばかりです。

商品が売れるとメルカリの画面上から QR が出力出来るようになるので、これをファミマにおいてある Fami ポートで読み込ませて伝票を出し、レジへ発送商品と共に持っていくと、伝票を入れるためのシートをくれるのでこれを箱に貼り、伝票をその中に入れて店員さんに渡すだけで終わりです。

続きを読む