旅行好きなソフトエンジニアの備忘録

プログラミングや技術関連のメモを始めました

【ディープラーニング】 不均衡データへの対処法

ディープラーニングというより、機械学習全般で起こりうる問題として不均衡データ問題があります。例えばラベル0のデータが99個あり、ラベル1のデータが1個しかない、といったように教師データのバランスが悪い場合、モデルは「とりあえず0と回答すれば99%の正解率が得られる」というようなずる賢い学習をしてしまいます。
この対処法の一つとしてこちらの論文(https://users.cs.fiu.edu/~chens/PDF/ISM15.pdf)ではデータの与え方を工夫しているのですが、自分のケースではかなり有効だったため、論文のpp.3に書いてある疑似コードをメモします。

!!!注意!!!
元の論文では"for N"の外側でCNNのトレーニングを行っていますが、kerasはデフォルトではトレーニングデータをシャッフルするので、内側でトレーニングした方が正例と負例の比率が意図した通りに保たれるので良いと考え意図的に変更しています

1. トレーニングデータを負例(大量)と正例(少量)に分割する
2. 負例をN個のバッチに分割する
3. for エポック
4.     for N
5.         ランダムにNp個の正例をピックアップする
6.         負例、正例を混ぜる
7.         CNNのトレーニング

f:id:ni4muraano:20170607225555p:plain

【WPF】 Contentに改行付きのテキストを書く

Contentに改行を付けたくて、その方法がここ(【WPF】コントロールのContentプロパティにテキストを改行して表示する - Microsoft.NET WPF - Project Group )で分かったのでメモします。

<!--&#10;が改行を表しています-->
<Button Content="Hello World&#10;\(^o^)/" IsHitTestVisible="False"/>

f:id:ni4muraano:20170602225033p:plain

【OpenCV】 画像を合成する(アルファブレンディング)

// 画像を読み込む
Mat lenna;
imread("lenna.jpg").copyTo(lenna);
if (lenna.empty())
{
    throw runtime_error("Failed to open image");
}

// 画像を読み込む
Mat clock;
imread("clock.jpg").copyTo(clock);
if (clock.empty())
{
    throw runtime_error("Failed to open image");
}

// 画像を1:1の割合で合成する
Mat destination;
addWeighted(lenna, 0.5, clock, 0.5, 0.0, destination);

f:id:ni4muraano:20170524221233j:plain:w150 f:id:ni4muraano:20170524221246j:plain:w150 f:id:ni4muraano:20170524221256j:plain:w150

【Python】 ndarrayのインデキシング

書籍「科学技術計算のためのPYTHON入門」のメモです。ndarrayのインデキシングについて今まで何も意識せず使っていたのですが、書籍にまとめられていたのでメモします。

  • 基本インデキシング(ビューが生成される)
# ndarray_viewの変更がndarrayにも影響を及ぼす
ndarray_view = ndarray[1, :]
  • 応用インデキシング(コピーが生成される)
    • ブール値インデキシング
    • 整数配列インデキシング
# ブール値インデキシングの例
# 0.5より大きい箇所のみ取り出す
# maskedを変更してもndarrayに影響を及ぼさない
mask = ndarray > 0.5
masked = ndarray[mask]

# 整数配列インデキシングの例
# (0,2), (2,0), (1,3)の位置の要素を取り出す
# extractedを変更してもndarrayに影響を及ぼさない
extracted = ndarray[[0, 2, 1], [2, 0, 3]]

科学技術計算のためのPython入門 ――開発基礎、必須ライブラリ、高速化

科学技術計算のためのPython入門 ――開発基礎、必須ライブラリ、高速化

【OpenCV】 照明ムラがある環境での二値化

照明ムラがある環境下で二値化を行い対象物を抽出しようとする場合、普通に二値化処理を行うと大抵上手く抽出できません。
下の画像はその例で、画像上部が明るめ、画像下部が暗めのになっています。この画像から米粒を抜き出そうとして大津の方法を適用すると、照明ムラの影響を受けて上手く抽出できていないことが分かります。
f:id:ni4muraano:20170520213509p:plain:w200    f:id:ni4muraano:20170520213534j:plain:w200
このような時の対処法の例がMathWorksのホームページに掲載されており、今回はOpenCVで実装します。

jp.mathworks.com

// 画像をグレースケールで読み込む
Mat gray;
imread("non_uniform_illumination_example.png", IMREAD_GRAYSCALE).copyTo(gray);
if (gray.empty())
{
    throw runtime_error("Failed to open image");
}

// オープニングを実行して背景を取り出す
Mat element = getStructuringElement(MORPH_ELLIPSE, cv::Size(15, 15));
Mat background;
morphologyEx(gray, background, CV_MOP_OPEN, element);

// 前景を取得する
Mat foreground;
absdiff(gray, background, foreground);

// 二値化して米粒を抽出する
Mat binary;
threshold(foreground, binary, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

f:id:ni4muraano:20170520213509p:plain
元画像

f:id:ni4muraano:20170520214658j:plain
背景

f:id:ni4muraano:20170520214708j:plain
前景

f:id:ni4muraano:20170520214715j:plain
米粒

【料理】 鶏肉のカリカリ焼き・ネギ塩レモンソース

たまに料理を作るのですが、また作る事があるかもしれないのでメモしておきます。

recipe.rakuten.co.jp

材料(2人分)

もも肉 2枚 ⇒ 1枚(350~400g、小食なので二枚は多い)
ネギ   1本
ごま油  大さじ2
塩    小さじ1/2
こしょう 適量
レモン汁 大さじ1 ⇒ 大さじ0.7位(酸っぱいと感じた)

1. フライパンを温めて、皮を下にして鶏もも肉を焼く

  • アルミホイルをひいた上から水を入れた小さい鍋を使って肉を押さえ付けるとカリカリになった
  • 7~10分焼いたと思う

2. 反対側を焼く

3. ネギ塩だれを作る

  • ネギをみじん切りにする
  • ごま油、塩、レモン汁を入れる
  • フライパンに入れ、中火でネギを少し炒める

4. 鶏肉を食べやすい大きさに切る

【OpenCV】 forループを使わずに指定した色を別の色に変更する

ディープラーニングの前処理として、画像のある色を別の色に変更しようとしていました。ただ、NumPyではforループをなるべく使用しないことが推奨されているため、どうやって実現すれば良いのか悩んでいましたが、ここ(Replace a range of colors with a specific color in python - OpenCV Q&A Forum)にアドバイスがありました。

import cv2
import numpy as np

image = cv2.imread('lenna.jpg')
# 画像の黒い部分を白に置き換える
black = [0, 0, 0]
white = [255, 255, 255]
image[np.where((image == black).all(axis=2))] = white