Bash(Shell)でディレクトリ、リストをforループする

よく使うのでメモとして掲載します。

Bash(Shell)でディレクトリ、リストをforループする サンプルコード


#!/bin/bash

echo "ディレクトリ直下のファイルをループ"
dir_path="sample_dir/*"
for dir in $dir_path; do
    echo "$dir"
done

echo --------------------------

# リスト定義
declare -a list=(
    "foo"
    "bar"
    "baz"
)

echo "リストをループする"
for row in "${list[@]}"; do
    echo "$row"
done

echo "インデックス付きでリストをループする"
for i in "${!list[@]}"; do
    echo "$i : ${list[$i]}"
done

echo --------------------------

echo "連番でループ{}"
for i in {0..3}; do
    echo ${i}
done

echo "連番でループ seq"
for i in $(seq 0 3); do
    echo "$i"
done

実行結果


# ディレクトリ直下のファイルをループ
sample_dir/sample_01.txt
sample_dir/sample_02.txt
--------------------------
# リストをループする
foo
bar
baz
# インデックス付きでリストをループする
0 : foo
1 : bar
2 : baz
--------------------------
# 連番でループ{ }
0
1
2
3
# 連番でループ seq
0
1
2
3


ディレクトリ直下のファイルをfor文でループ


#!/bin/bash

# ディレクトリ直下のファイルをループ
dir_path="sample_dir/*"
echo "\$dir_path -> " $dir_path
for dir in $dir_path; do
    echo "$dir"
done

# 結果
# 
# $dir_path ->  sample_dir/sample_01.txt sample_dir/sample_02.txt
# sample_dir/sample_01.txt
# sample_dir/sample_02.txt


リストをfor文でループ、インデックス付きfor文でループ

#!/bin/bash

# リスト定義
declare -a list=(
    "foo"
    "bar"
    "baz"
)

# リストをループする
echo "\$\"{list[@]}\" -> " "${list[@]}"
for row in "${list[@]}"; do
    echo "$row"
done

echo

# インデックス付きでリストをループする
echo "\$\"{!list[@]}\" -> " "${!list[@]}"
for i in "${!list[@]}"; do
    echo "$i : ${list[$i]}"
done

# 結果
# 
# $"{list[@]}" ->  foo bar baz
# foo
# bar
# baz

# $"{!list[@]}" ->  0 1 2
# 0 : foo
# 1 : bar
# 2 : baz


連番をfor文でループ


#!/bin/bash

# 連番でループ {}
echo "{0..3} -> " {0..3}
for i in {0..3}; do
    echo ${i}
done

echo

# 連番でループ seq
echo "\$(seq 0 3) -> " $(seq 0 3)
for i in $(seq 0 3); do
    echo "$i"
done

# 結果
#
# {0..3} ->  0 1 2 3
# 0
# 1
# 2
# 3

# $(seq 0 3) ->  0 1 2 3
# 0
# 1
# 2
# 3

IBM WatsonのVisual Recognitionの独自クラスで画像認識する (Python)

前回、shellとCurlで利用してみましたが、今回はPythonで独自クラスを利用してみます。

shellとCurlのサンプルコード掲載投稿はこちら

Visual Recognitionで画像認識する

shellとCurlでやったおさらいとなります。アカウントを作成し、APIキーを取得したら、classifyメソッドを利用して画像認識を行います。

画像識別するフルーツの画像

https://watson-developer-cloud.github.io/doc-tutorial-downloads/visual-recognition/fruitbowl.jpg


PythonでWatsonを利用するには、pipで”ibm-watson”モジュールをインストールします。

ibm-watsonモジュールをpipでインストール

# ibm-watsonをインストールする
pip install --upgrade "ibm-watson>=4.1.0"

Python 画像認識 classify サンプルコード

import json
from ibm_watson import VisualRecognitionV3
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

authenticator = IAMAuthenticator("{api keyを設定する}")
visual_recognition = VisualRecognitionV3(
    version="2018-03-19", authenticator=authenticator
)

visual_recognition.set_service_url(
    "https://api.us-south.visual-recognition.watson.cloud.ibm.com"
)

with open("fruitbowl.jpg", "rb") as images_file:
    classes = visual_recognition.classify(
        images_file=images_file,
        accept_language="ja",
        threshold="0.6"
    ).get_result()
    print(json.dumps(classes, ensure_ascii=False, indent=2))

APIKEYとバージョンを指定して、VisualRecognitionインスタンスを生成します。

set_service_urlでエンドポイントのURLを指定します。

VisualRecognitionのclassifyのパラメータに以下を指定します。

  • images_file・・・画像ファイル
  • accept_language・・・言語
  • threshold・・・しきい値(返却される分類のスコアの最低値)


classifyの実行結果

$ python classify.py 
{
  "images": [
    {
      "classifiers": [
        {
          "classifier_id": "default",
          "name": "default",
          "classes": [
            {
              "class": "果実",
              "score": 0.788
            },
            {
              "class": "オリーブ色",
              "score": 0.973
            },
            {
              "class": "レモン・イエロー (色)",
              "score": 0.789
            }
          ]
        }
      ],
      "image": "fruitbowl.jpg"
    }
  ],
  "images_processed": 1,
  "custom_classes": 0
}

結果が取得できました。レスポンスの各値については、公式ドキュメントをご参照ください。

公式ドキュメントURL

https://cloud.ibm.com/apidocs/visual-recognition/visual-recognition-v3?code=python#classify-images


Visual Recognitionで画像認識用の独自クラスを作成する

サンプルで記載されている犬の画像セット3つと猫の画像セット1つを利用して独自クラスを作成します。犬の画像はポジティブ、猫の画像はネガティブな学習データとして利用します。

画像URLは公式ドキュメントのページから取得できます。公式ドキュメントのURLはこちら

Python 独自クラス作成 create_classifier サンプルコード

import json
from ibm_watson import VisualRecognitionV3
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator


def exec():
    authenticator = IAMAuthenticator("{API KEYを設定する}")
    visual_recognition = VisualRecognitionV3(
        version="2018-03-19", authenticator=authenticator
    )

    visual_recognition.set_service_url(
        "https://api.us-south.visual-recognition.watson.cloud.ibm.com"
    )

    with open("beagle.zip", "rb") as beagle, open(
        "golden-retriever.zip", "rb"
    ) as goldenretriever, open("husky.zip", "rb") as husky, open(
        "cats.zip", "rb"
    ) as cats:
        model = visual_recognition.create_classifier(
            "dogs",
            positive_examples={
                "beagle": beagle,
                "goldenretriever": goldenretriever,
                "husky": husky,
            },
            negative_examples=cats,
        ).get_result()
    print(json.dumps(model, indent=2))


if __name__ == "__main__":
    exec()

API KEYを設定してVisualRecognitionインスタンスを生成し、サービスのURLを設定するところまでは、classifyメソッドと同じです。

学習用画像データが入ったzipファイルをwith openで展開します。カンマ区切りで繋げることで、4つのzipファイルを引数に渡します。

独自クラスを作るには、create_classifierメソッド作成します。第一引数には、nameを指定します。positive_examplesでは、犬のクラスを構成する画像ファイルをclassnameキーと一緒に指定します (”beagle”: beagle、”goldenretriever”: goldenretriever、”husky”: husky) 。negative_examplesには、猫の画像ファイルを指定してます。ネガティブ例にはクラス名の指定は不要です。

なお、 .jpgまたは.pngの画像ファイルが 1つのzipに最低でも10個必要で、最大数は10,000画像 または 100MBのようです。

create_classifierの実行結果

$ python create_classifier.py
{
  "classifier_id": "dogs_113492332",
  "name": "dogs",
  "status": "training",
  "owner": "7b33a505-95fc-4f71-a419-17a78f96f78c",
  "created": "2019-12-28T21:19:02.872Z",
  "updated": "2019-12-28T21:19:02.872Z",
  "classes": [
    {
      "class": "husky"
    },
    {
      "class": "goldenretriever"
    },
    {
      "class": "beagle"
    }
  ],
  "core_ml_enabled": true
}

結果が取得できました。レスポンスの各値については、公式ドキュメントをご参照ください。

公式ドキュメントURL

https://cloud.ibm.com/apidocs/visual-recognition/visual-recognition-v3#create-a-classifier

独自クラスを利用するには最初のclassifyメソッドのパラメータに”owners=[“me”]”を追加します。

犬(ハスキー)の画像を独自クラスとデフォルトクラスとで、それぞれ画像認識してみます。

独自クラス classify 実行結果

{
  "images": [
    {
      "classifiers": [
        {
          "classifier_id": "dogs_113492332",
          "name": "dogs",
          "classes": [
            {
              "class": "husky",
              "score": 0.843
            }
          ]
        }
      ],
      "image": "husky2.jpg"
    }
  ],
  "images_processed": 1,
  "custom_classes": 3
}

huskyクラスで、0.843という結果が返却されました。また、独自クラスの言語は日本語指定できないようです。

デフォルトクラス classify 実行結果

{
  "images": [
    {
      "classifiers": [
        {
          "classifier_id": "default",
          "name": "default",
          "classes": [
            {
              "class": "犬",
              "score": 0.98,
              "type_hierarchy": "/動物/哺乳類/肉食動物/イヌ/犬"
            },
            {
              "class": "イヌ",
              "score": 0.887
            },
            {
              "class": "肉食動物",
              "score": 0.887
            },
            {
              "class": "哺乳類",
              "score": 0.887
            },
            {
              "class": "動物",
              "score": 0.982
            },
            {
              "class": "シベリアン・ハスキー",
              "score": 0.739,
              "type_hierarchy": "/動物/飼い慣らされた動物/犬/シベリアン・ハスキー"
            },
            {
              "class": "飼い慣らされた動物",
              "score": 0.883
            },
            {
              "class": "灰白色",
              "score": 0.807
            },
            {
              "class": "緑がかった色",
              "score": 0.79
            }
          ]
        }
      ],
      "image": "husky2.jpg"
    }
  ],
  "images_processed": 1,
  "custom_classes": 0
}

犬で0.98、何故かカタカナのイヌでも0.887、シベリアン・ハスキーが0.739、また色も識別できています。

ハスキーかどうかのスコア0.843>0.739と、独自クラスのほうが優秀だといえるのでしょうか。

しかし、犬が0.98など色々返却されるデフォルトのほうがなんとなく優秀そうな。。。学習量を増やした場合、精度どのくらいあがるかなど、もう少し検証したいと思います。

PostgreSQL psqlで引数とSQLファイルを指定して実行する

psqlとはPostgreSQLのターミナル型SQLクライアントです。

引数に指定した値をSQLファイルの変数にバインドします。

psqlで引数とSQLファイルを指定して実行する サンプルコード

sample.sql

実行するSQLファイル、”:変数”の箇所を置き換えます。

select :foo,
       :bar,
       :hoge;

p_exec_file.sh

実行するshellです。psqlを呼び出し、”-f”オプションでSQLファイルを指定し、”-v”オプションで引数名と値を設定します。”–echo-all”は実行したSQLを結果と一緒に出力します。

#!/bin/bash

DB_USER="{user_name}"
DB_PWD="{password}"
DB_SERVER="{db_server_url}"
DB_PORT="{db_port}"
DB_NAME="{db_name}"

psql \
    -d "postgresql://$DB_USER:$DB_PWD@$DB_SERVER:$DB_PORT/$DB_NAME" \
    -f "sample.sql" \
    -v foo="now()" \
    -v bar="1" \
    -v hoge="'test_str'" \
    --echo-all


実行結果

p_exec_file.shを実行します。実行したSQL文と結果が出力されます。”foo”に”now()”、”bar”に”1″(数値)、”hoge”に”test_str”(文字)が設定されています。

$ ./p_exec_file.sh
select :foo,
       :bar,
       :hoge;
              now              | ?column? | ?column?
-------------------------------+----------+----------
 2019-12-28 16:10:25.343578+09 |        1 | test_str
(1 行)

Crl2CapでWindowsのCtrlとCapsLockを入れ替える

自分が新しくWindowsをインストールしたら最初にやることの一つです。

CtrlキーとCapsLockキーを入れ替えます。MicroSoft純正で安心感もあります。

公式URLはこちら


管理者権限でコマンドプロンプトを起動して、以下のコマンドを実行します。

ctrl2cap /install

実行完了したらWindowsを再起動すれば完了です。

IBM WatsonのVisual Recognitionで画像認識する(Curl)


Visual Recognitionとは?

Visual RecognitionはIBM社のWatsonが提供する画像認識機能です。

以下は、公式ページの説明です。

Visual RecognitionはWatsonの画像認識機能です。すぐにお使いいただけるようにWatsonが既に学習をしており、画像・映像フレームに写った複数のものや、情景を分析・認識することができます。また、機械学習によりWatsonに独自の学習をさせることもできます。すでに、自社製品の認識・分類や、製造ラインにおける欠陥検出といった多種多様なお客様の業務で、高い精度の画像認識を少ない画像枚数による短時間の機械学習で実現しています。さらに、日本語・英語を含む多数の言語で認識結果を返すことができます。

https://www.ibm.com/watson/jp-ja/developercloud/visual-recognition.html


公式ページにもあるように、事前学習済みのため、サービス利用するために、アカウントを作成すれば、すぐに利用できるようです。(制限があるが無料で利用可能)


Visual Recognitionで画像認識する

アカウントを作成し、APIキーを取得したら、classifyメソッドを利用して画像認識を行います。

画像識別するフルーツの画像

https://watson-developer-cloud.github.io/doc-tutorial-downloads/visual-recognition/fruitbowl.jpg


classify curl 画像URL指定 サンプルコード


#!/bin/bash

# api key
api_key="API KEYを設定する"
# service end_point
end_point="https://api.us-south.visual-recognition.watson.cloud.ibm.com"
method="v3/classify"
url="$end_point/$method"

# フルーツの画像
image_url="https://watson-developer-cloud.github.io/doc-tutorial-downloads/visual-recognition/fruitbowl.jpg"

# Visual Recognitionのclassifyへ送信
curl -u "apikey:$api_key" \
    "$url?url=$image_url&version=2018-03-19&Accept-Language=ja"

Visual RecognitionのclassifyメソッドへCurlを使ってGETします。アカウントを作成後に取得したAPIキー、画像のURLを指定します。

※今回はサンプルで利用されているフルーツの画像を利用。

classify 実行結果(JSON)


{
    "images": [
        {
            "classifiers": [
                {
                    "classifier_id": "default",
                    "name": "default",
                    "classes": [
                        {
                            "class": "バナナ",
                            "score": 0.562,
                            "type_hierarchy": "/果実/バナナ"
                        },
                        {
                            "class": "果実",
                            "score": 0.788
                        },
                        {
                            "class": "規定食 (食品)",
                            "score": 0.528,
                            "type_hierarchy": "/食物/規定食 (食品)"
                        },
                        {
                            "class": "食物",
                            "score": 0.528
                        },
                        {
                            "class": "ハネデュー",
                            "score": 0.5,
                            "type_hierarchy": "/果実/メロン/ハネデュー"
                        },
                        {
                            "class": "メロン",
                            "score": 0.501
                        },
                        {
                            "class": "オリーブ色",
                            "score": 0.973
                        },
                        {
                            "class": "レモン・イエロー (色)",
                            "score": 0.789
                        }
                    ]
                }
            ],
            "source_url": "https://watson-developer-cloud.github.io/doc-tutorial-downloads/visual-recognition/fruitbowl.jpg",
            "resolved_url": "https://watson-developer-cloud.github.io/doc-tutorial-downloads/visual-recognition/fruitbowl.jpg"
        }
    ],
    "images_processed": 1,
    "custom_classes": 0
}


結果は、JSON形式で返却されます。”class”にバナナ、果実、メロン、 オリーブ色などクラス名が、”score”に0~1の範囲で プロパティの信頼スコアが返却されます。スコアが高いほど、クラスが画像に描かれている可能性が高くなります。


classify curl ローカル画像指定 サンプルコード


#!/bin/bash

# api key
api_key="API KEYを指定する"
# service end_point
end_point="https://api.us-south.visual-recognition.watson.cloud.ibm.com"
method="v3/classify"
url="$end_point/$method"

# 画像のパス
image_path="img/fruitbowl.jpg"

# Visual Recognitionのclassifyへ送信
curl -X POST \
    -u "apikey:$api_key" \
    -F "images_file=@$image_path" \
    -F "threshold=0.6" \
    "$url?version=2018-03-19&Accept-Language=ja"


ローカル画像を利用するには、POSTを指定して、@ファイル名でローカル画像のパスを指定します。”threshold”で返却する閾値を指定します。上記の例だと、0.6以上のもののみ取得。

classify 実行結果(JSON)

{
    "images": [
        {
            "classifiers": [
                {
                    "classifier_id": "default",
                    "name": "default",
                    "classes": [
                        {
                            "class": "果実",
                            "score": 0.788
                        },
                        {
                            "class": "オリーブ色",
                            "score": 0.973
                        },
                        {
                            "class": "レモン・イエロー (色)",
                            "score": 0.789
                        }
                    ]
                }
            ],
            "image": "fruitbowl.jpg"
        }
    ],
    "images_processed": 1,
    "custom_classes": 0
}

WEBのURLで画像を指定した場合と同様の結果が取得できました。ただし、今回は”threshold”で0.6を指定したため、0.6以上のスコアの分類しか取得していません。


感想

アカウント作成から利用まで、すごく簡単でした。zip画像を送ると独自モデルも利用できるようなので、次はそちらを利用しみたいと思います。他にも人、犬、猫なども分類してみました。

以下、猫、犬の結果例です。

猫の画像の実行結果(サンプル)

{
    "images": [
        {
            "classifiers": [
                {
                    "classifier_id": "default",
                    "name": "default",
                    "classes": [
                        {
                            "class": "ネコ",
                            "score": 1,
                            "type_hierarchy": "/動物/哺乳類/肉食動物/ネコ"
                        },
                        {
                            "class": "肉食動物",
                            "score": 0.989
                        },
                        {
                            "class": "哺乳類",
                            "score": 0.989
                        },
                        {
                            "class": "動物",
                            "score": 0.989
                        },
                        {
                            "class": "ベージュ色",
                            "score": 0.991
                        }
                    ]
                }
            ],
            "image": "cat_1.jpg"
        }
    ],
    "images_processed": 1,
    "custom_classes": 0
}

犬の画像の実行結果(サンプル)

{
    "images": [
        {
            "classifiers": [
                {
                    "classifier_id": "default",
                    "name": "default",
                    "classes": [
                        {
                            "class": "シベリアン・ハスキー",
                            "score": 0.875,
                            "type_hierarchy": "/動物/飼い慣らされた動物/犬/シベリアン・ハスキー"
                        },
                        {
                            "class": "犬",
                            "score": 0.987
                        },
                        {
                            "class": "飼い慣らされた動物",
                            "score": 0.987
                        },
                        {
                            "class": "動物",
                            "score": 0.987
                        },
                        {
                            "class": "エスキモー・ドッグ",
                            "score": 0.865,
                            "type_hierarchy": "/動物/飼い慣らされた動物/犬/エスキモー・ドッグ"
                        },
                        {
                            "class": "アジュール (色)",
                            "score": 0.903
                        },
                        {
                            "class": "灰白色",
                            "score": 0.867
                        }
                    ]
                }
            ],
            "image": "husky1.jpg"
        }
    ],
    "images_processed": 1,
    "custom_classes": 0
}

Python ディレクトリの存在チェックして、存在しなければ作成する

よく使うので、メモ。

Pythonでディレクトリの存在チェックして、存在しなければ作成する

ディレクトリの存在チェックと作成するサンプルコード

import os

SAMPLE_DIR = "sample"

if not os.path.exists(SAMPLE_DIR):
    # ディレクトリが存在しない場合、ディレクトリを作成する
    os.makedirs(SAMPLE_DIR)

os.path.exists関数にディレクトリのパスを渡します。ディレクトリが存在する場合は、True。存在しない場合は、Falseが返却されます。

os.makedirs関数にディレクトリのパスを渡してディレクトリを作成します。

※上記の記述はファイルが存在した場合も、Trueとなります。

長めのサンプルコード

import os

SAMPLE_DIR = "sample2"


# 存在チェック
if os.path.isdir(SAMPLE_DIR):
    print("ディレクトリが存在します")
else:
    print("ディレクトリが存在しません")

# ディレクトリがない場合、作成する
if not os.path.exists(SAMPLE_DIR):
    print("ディレクトリを作成します")
    os.makedirs(SAMPLE_DIR)

# 存在チェック
if os.path.isdir(SAMPLE_DIR):
    print("ディレクトリが存在します")
else:
    print("ディレクトリが存在しません")


長めのサンプルコードでは、ディレクトリの存在チェックにos.path.isdirを利用しています。この関数を利用すれば、ファイルの場合はFalseが帰ってきます。

実行例

>>python check_exists_dir.py

ディレクトリが存在しません
ディレクトリを作成します
ディレクトリが存在します

WordPressでカテゴリー毎の投稿を一覧表示するショートコードを作成する

WordPressの固定ページに指定したカテゴリーidの投稿リストを表示するショートコードです。

functions.phpへ以下のコードを追加して、ショートコードを定義します。

カテゴリー毎の投稿を一覧表示するショートコード

// 投稿を取得する
// num_p:表示数
// id:カテゴリーID
// [p_list id=2 num_p=3]
function get_post_list($atts)
{
  $a = shortcode_atts(array(
    'num_p' => 20,
    'id' => 1
  ), $atts);
  $args = array(
    'numberposts'  => $a['num_p'],
    'category'    => $a['id']
  );
  $my_posts = get_posts($args);

  if (!empty($my_posts)) {
    $output =  '<ul>';
    foreach ($my_posts as $p) {
      $output .= '<li><a href="' . get_permalink($p->ID) . '">'
        . $p->post_title . '</a></li>';
    }
    $output .= '<ul>';
  }
  return $output ?? '<strong>条件に一致する投稿がありません</strong>';
}
// ショートコード
add_shortcode('p_list', 'get_post_list');

例) ショートコード使用1

[p_list id=8]

HTML編集で記載します。[get_p_list]でショートコードを指定し、引数として[id]の”8″を渡しています。カテゴリーIDが8の投稿リストを表示します。

例)ショートコード使用2

 [p_list id=8 num_p=3]

上記は、カテゴリーidの”8″の投稿取得して、投稿3つを表示します。

例) 実際の表示