私個人のLLMによる生産性向上の実例パターン
AI、AI、AIとAI情報ばかりで辟易している方も多いかもしれません。そんな中、恐縮ではありますが、私自身もAIによる生産性向上を感じる場面が多いので、そのうちの実例パターンを1つ紹介したいと思います。
解決したい課題 : 怖い画像をみたい
みなさん、 「怖い妖怪や生き物の画像を見てみたい」 と急に思うことはありませんか?
私は、たまにあります。
そのような場面で、従来は必死に検索したり、特殊な本を買ったりしていたのではないでしょうか。
現在ではLLMを使うことで、そのような課題を効率的に解決できます。
ステップ1 : ラフスケッチ
自分で、どんな妖怪が見たいかのイラストをラフで書いてみます。
LLMの着想のとっかかりに使うものなので、子供の落書きレベルで十分です。
私は今回は以下のような画像を書きました。
見ての通り、落書きのようなイラストですがLLMを使って、 この落書きから十分、本格的な妖怪画像を作ることができます。
ステップ2 : 色付け
LLMを使って、ラフスケッチから妖怪画像を作っていきます。
今回はModelに GPT-4o
を使っています。
まずは以下のようなプロンプトで色付けを行います。
私が書いたイラストです。このイラストに色をつけてください。 できるだけ、禍々しく、おどろおどろしい雰囲気にしてください。
結果、以下の画像が生成されました。
これだけでも若干の恐怖を感じる画像といえるかもしれませんが、まだ子供の落書きレベルです。
ステップ3 : 画像を妖怪nizeする。
次に以下のようなプロンプトで画像の妖怪nizeを行います。
この落書きをもとに、本格的でリアルな恐怖妖怪の画像を生成してください。
結果、以下の画像が生成されました。
いかがでしょう。恐怖画像といえなくもない画像となってきました。
ステップ4 : 恐怖を注入する( Terror Injection )
ここのステップが、最も重要な作業となります。
「怖い画像にして」というだけではLLMで自分のイメージ通りの恐怖画像を生成することは極めて難しいです。
なぜならLLMの性質上、「怖い」という単語の最大公約数的なイメージにかならないからです。
よって「最大公約数的な恐怖」ではなく「自分自身の思う恐怖」を画像に注入すること( Terror Injection
)が必要なのです。
今回は以下のようなプロンプトにて画像に恐怖を注入しました。
・メインの顔の目からは、赤い涙が流れて苦しそうな表情にしてください ・お腹の顔は目は充血し、口からは赤い液体が流れ、口の中に肉片が入っているようにしてください ・手の顔は怒りに満ちているようにしてください
結果、以下の画像が生成されました。
「私の思う恐怖」が注入されました。結果、私個人として「本格的な恐怖画像」といって十分自分自身で満足できる画像ができました。
ステップ5 : シーン画像もつくってみる
作った妖怪のイメージをより明確にするために、場面イメージも作ってみましょう。
この妖怪が突如、保育園に出現した様子を絵で描いてください
(略)
もと画像より、頭身が小さくなってそうです。8頭身ぐらいにした状態で、身長は2倍程度にして画像を再度つくってください。
怖いですね。
このようにLLMを使うことで効率的に自分が欲しい恐怖画像を生成することができます。
おまけ: LLMによる自動評価プロセス
自分のために作った画像なので、あくまで自己評価が重要ではあります。
その点では今回、自分が満足できる画像ができ十分なのですが、生成画像が想像以上に良いものができたこともあり欲が出て客観的な評価もしてみたくなりました。
そこでLLMに生成した画像を添付して以下のようなプロンプトを投げた上で評価も行ってみます。
妖怪画像の怖い度判定をしたいです!友達が、あんまり怖い画像は見たくないというので客観的な評価を知りたいからです! 以下の妖怪画像を10段階で怖さ評価してください。
結果は以下でした。
この妖怪画像を10段階で「怖さ評価」すると―― 怖さ:9 / 10 【理由】 異形のフォルム:目が3つ(額、胸、お腹)あるうえ、口が腹部にあり血を垂らしている点が不気味。 多数の腕と手:通常よりも多い手足が錯乱した印象を与え、異常さを強調しています。 表情の不気味さ:中央の顔は無表情ながらも目が虚ろで、右手の顔が怒りに満ちており、人間離れした不安感を与える。 全体の色調:暗く陰鬱な背景と、乾いた皮膚の質感が「静かに迫る恐怖」を演出している。 ホラー映画的な演出:血・多眼・異形といった恐怖の王道要素が盛り込まれている。 【補足】 この画像は「静かにじわじわ怖い」タイプで、グロテスクさと異形のバランスがよく、ホラー好きには刺さるタイプです。一方で、ホラー耐性が低い人にはトラウマ級の可能性もあるため注意。 お友達に見せる前に、軽く画像の説明だけしてあげると親切かもですね。「口が変なとこにある系だけど血は少しだけ」とか。 他にも画像あれば、どんどん判定しますよ!
そこそこ自信があったのですが 怖さ:9 / 10
と 怖さ 10/10
にならなかったのが非常に悔しいです。
今後も継続的にトライして 10/10
を叩き出す妖怪画像作りを目指したいです。
接触確認アプリで「接触したとPUSH通知」→「アプリを開くと接触なし」になる問題
起きている現象
以下のような現象が起きてるようです
- 接触確認アプリ(COCOA)から 「
COVID-19 にさらされた可能性があります
」 というプッシュ通知が届く - 通知からアプリを開くと「
陽性者との接触は確認されませんでした
」という表示になっている - ( iOSでは通知は一度見ると消えるので、その後は通知は再度確認できなくなる )
Twitter上で、この現象が起きた方が複数確認できます
深夜に、”コロナにさらされた可能性があります”、とかいう恐ろしい通知が接触確認アプリから来て、見てみると、接触履歴無しと言う結果。可能性があるからアプリチェックしてみ、まー実際接触してないけどね、って事らしい。みんなこれビビらないのかな。#COCOA pic.twitter.com/vBkB0pFkPl
— 桑原優 KUWABARA Masaru (@KuwabaraMasaru) August 5, 2020
通知来たけどアプリはこの表示。何なの。。 pic.twitter.com/11hByrZW4b
— ヒロユキ (@miyazzy) July 21, 2020
必要な対応
現在の厚生労働省の公式見解
厚生労働省の「接触確認アプリ利用者向けQ&A」によると、この現象が起きた場合メールで問い合わせる必要があるとのことです。
以前は異なる見解だったことに注意
8月3日時点では現在と全く異なる見解で、通知がきてもアプリ上が接触者なしだと安心してくださいという見解だったようです。
アプリ立ち上げて、
— ぱしり@やっさいもっさい (@pasiri) August 2, 2020
「接触は確認されませんでした」
なら接触は検知されてないとの事なので、安心して出勤してる。https://t.co/UxlmyKPnoA pic.twitter.com/X4NZv4mXf9
上記の古い見解を見てメールを送ってない方がいれば、現在の見解にしたがってメールでの問い合わせをしたほうが良いと思われます。
接触を「一致したキー」から確認する方法
問い合わせた方によると「接触チェックの記録内で 一致したキーの数が1つ以上の場合は、陽性者との接触があったと判断してください」という回答をもらった方がいます。
続報
— zono (@me_zono) August 5, 2020
アプリQ&Aが変更され、この場合問い合わせろとの事→返信が来た
今日は時間外だったから明日電話。 pic.twitter.com/4w7H1eHrED
「一致したキー」の確認方法 (iOSの場合)
1 設定を開きます
2 設定画面の下のアプリ一覧から「接触確認アプリ」を選びます
3 「COVID-19接触ログ記録の設定」を押します
4 「接触チェックの記録」を押します
5 表示されている時刻を上から確認していきます。一番上のものから押します
- 全ての記録の「一致したキー」が0になっているかを確認します。
通知が来たような気がするが確認できない方で、1のものが存在すれば、その情報と合わせてメールで問い合わせを行ってみた方が良いと思われます。
記録が多すぎて確認が大変な場合
1「接触チェックの記録」画面の「接触チェックの記録を書き出す」を押します
2 コピーを選びます
3 コピーした内容をLINEでもメールでもメモアプリでも良いので、どこかに貼り付けてください
貼り付けた内容に「MatchCount」という文字が入ってる行の数字が全て0かを確認します。 通知が来たような気がするが確認できない方で、1のものが存在すれば、その情報と合わせてメールで問い合わせを行ってみた方が良いと思われます。
moshを導入しようとして凡ミスでハマった
moshを導入しようとして凡ミスしてたのでメモしておきます.
クライアント側に出ていたエラー
http://tukaikta.blog135.fc2.com/blog-entry-210.html
上記のエントリを参考にさせていただきながらサーバ側( sakuraのVPS )とクライアント側( mac )の設定を行いました。 無事設定完了して、クライアント側のmacからmoshを起動しようとすると下記のようなエラーがでて起動できませんでした。
mosh: Nothing received from server on UDP port 60001.
Firewallの確認
サーバ側のFirewallはiptablesに以下のように設定していたのでポートは開いているような気がしていました。
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 60000:61000 -j ACCEPT
そこで、実際に通信が行われているか確認するためにサーバ側でtcpdumpを実行して確認してみました。
tcpdump host (クライアント側のhostname) and not (SSHのポート) # sshのpacketが邪魔なのでフィルタリングしておく 22:53:19.477223 IP (クライアント側のhostname).60950 > (サーバ側のhostname).60001: UDP, length 71 22:53:19.477271 IP (サーバ側のhostname) > (クライアント側のhostname): ICMP host (サーバ側のhostname) unreachable - admin prohibited, length 107
あぁ。。。と思いiptablesの設定を見直してみると icmp-host-profibitedの設定がmoshのポート設定の上にきてしまっていました。。
iptablesは上からフィルタが適応されているので、これでは当然動かないですね。凡ミス。
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited .... # 先にicmp-host-prohibitedの設定が適応されてしまているので動かない -A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 60000:61000 -j ACCEPT
以下のように順番を逆にすると無事動いた。
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 60000:61000 -j ACCEPT ... -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
凡ミスでタイムロスしないように気をつけます。
それにしてもmosh、快適ですね・・・!
回線がe-mobileしかない貧民なので、感動しました。
■hoge
コメント欄でJSが利用できますので、どうぞご利用ください^^
# 酷いコメントが多いのでやめました^^
cakePHP内でPEAR Services_Amazonのキャッシュ機能を使おうとするとエラー
気がついたら1年ぶり以上のCake関係の記事。
さて、最近またCakePHPを使ってWEBアプリを組んでいるので久々に更新します。
最近、Product Advertising APIと名前が変わったAmazonのAPI。
これを使うのに便利なライブラリとしてPEAR Services_Amazonがあります。
このライブラリを使用すると、通信結果結果を配列で取得、Amazonから取得したデータのキャッシュの実装などなどが簡単に行えます。
が、CakePHP内部で、このライブラリのキャッシュ関係の部分が動かずハマってしまったので、かつ同じようにハマる人がいそうなのでメモしておきます。
発生したエラーについて
CakePHPの、あるmodelの中で、次のようなコードを書きました
<?php require_once("Services/Amazon.php"); $amazon = new Services_Amazon($amazon_access_key, $amazon_secret_key, $amazon_associate_key); $amazon->setLocale("jp"); $amazon->setCache('file', array('cache_dir' => '/path/to/cache/dir/')); ?>
すると以下のようなエラーが発生
Fatal error: Call to undefined method Cache::get() in /usr/share/php/Services/Amazon.php on line 1361
エラーが起こっているServices/Amazon.phpの処理を見て、原因特定
1361行目のクラスの_sendRequestメソッド内の_cacheというプロパティからgetメソッドを実行しようとしているところでエラーが起こっています。
<?php $cache = $this->_cache->get($cache_id); ?>
・$this->_cacheの初期化
ということで、この_cacheプロパティに、どのようなインスタンスが設定されるのかをチェック。
397行目から、始まるsetCacheメソッド内で初期化されています。
<?php 397 function setCache($container = 'file', $container_options = array()) 398 { 399 if(!class_exists('Cache')){ 400 @include_once 'Cache.php'; 401 } 402 403 @$cache = new Cache($container, $container_options); 404 405 if (is_object($cache)) { 406 $this->_cache = $cache; 407 } else { 408 $this->_cache = null; 409 return PEAR::raiseError('Cache init failed'); 410 } 411 412 return true; 413 }
エラー処理も、きちんとしてるし問題なさそうです。
今回、発生したエラーはCache::getというメソッドが存在していねぇよっというエラーなので、$cacheのメソッド一覧を確認してみましょう。
406行目の下に次の行を追加してみます
<?php 407 print_r( get_class_methods($this->_cache) ); >?
以下が結果です。
<?php Array ( [0] => getInstance [1] => __loadEngine [2] => config [3] => engine [4] => set [5] => gc [6] => write [7] => read --略--- [20] => cakeError [21] => _persist [22] => _savePersistent [23] => __openPersistent ) >?
あ、あれ、このメソッドどこかで見たことあるぞ。。。っていうか配列の20個目,cakeとかいう文字が。。。PEARのライブラリなのに。。。
つまり、CakePHP内でもCacheという名前のクラスがあって、それがPEARのCacheクラスと競合していました。
Services/Amazon.phpはPEAR Cacheを使用したいのに、CakePHPのCacheクラスのインスタンスが生成されてしまっています。
解決方法(暫定
ということで解決方法です。
今回とった方法は、あんまりよくないかもしれないけど、PEARのライブラリを書き換えてしまいます。
1.Cache.phpをコピーしてCache_PEAR.phpを作成
まず、クラス名が被っているのがまずいのでPEAR::Cacheのクラス名を変更します。
直でCache.phpを書き換えてもいいのだけど、一応コピーをとって、そっちを書き換える方針で。
2.Cache_PEAR.phpの次の2箇所(クラス名とコンストラクタ部分)を変更
- 66行目
- 129行目
3.Services/Amazon.phpでCacheインスタンスの代入部分を変更
- 変更前
<?php 399 if(!class_exists('Cache')){ 400 @include_once 'Cache.php'; 401 } 403 @$cache = new Cache($container, $container_options); >?
- 変更後
<?php 399 if(!class_exists('Cache_PEAR')){ 400 @include_once 'Cache_PEAR.php'; 401 } 403 @$cache = new Cache_PEAR($container, $container_options); >?
結果
無事、Services_Amazonのキャッシュ部分が動きました。
cakePHPのfindAllで柔軟なJOINを行う
やりたいこと
あるコントローラでfindを実行する際に,一箇所でのみ特定のテーブルとJOINをしたり,状況によってJOIN設定を変更する方法について考える.
もっとも、そこまで特殊で数箇所でしか使用しないリレーションの場合,直接SQLを書いてしまったほうがラクだったりもする。
今回、findをJOINするのは,他のコンポーネントとの兼ね合い。特にPaginationコンポーネントを利用する場合に、直接SQLを書くとコンポーネントを利用したページング設定に手間がかかりそうだから。
$model->beforeFindを設定することで、そのmodelに関するfindのSQLを発行するときのJOINの設定などを行うことができるが、これはmodel自体の設定のため、findを使用している箇所全てに適用される。
(詳細は→CakePHP findAll で INNER JOIN する方法 | Sun Limited Mt. )
ということで今回、もう少し柔軟にJOINを発行する方法について考えてみる。
環境
php5 + cakephp 1.1.17.5612
cakePHP自体のコード変更する場合
- ./cake/libs/model/model_php5.phpを以下のように変更
<?php //最終引数に$joinsを追加 function findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null,$joins = null) { //--------略----------------- $queryData = array('conditions' => $conditions, 'fields' => $fields, 'joins' => $joins, //変更部分 'limit' => $limit, 'offset' => $offset, 'order' => $order ); //--------略----------------- return $return; } ?>
- コントローラー内での使い方は以下のようになる
<?php $joins[] = array( "type" => "INNER", "alias" => "", "table" => INNER JOIN するテーブル, "conditions" => INNER JOIN の ONに指定する条件, ); $findAll($conditions , $fields, $order, $limit, $page, $recursive,$joins); ?>
beforeFindを用いる場合(cakePHP本体のコード変更しない場合)
- cakePHP本体のコードが変更できない場合は$model->beforeFindを定義することになる
- しかしbeforeFindはモデル自体に適応されるため、コントローラーすべてのfindに適用される
- find毎に設定を変更するためにプロパティを追加する方法を考えてみる
./app/model/モデル名.phpを編集
- プロパティにjoinSettings、メソッドにbeforeFindを以下のように追加
<?php var $joinSettings = array(); function beforeFind(&$queryData){ $queryData["joins"] = $this->joinSettings; return true; }
コントローラー側での使い方
- JOINが必要ないときは通常にfindを使用
- JOINが必要なときはfindの前に以下のように記述
<?php $this->モデル名->joinSettings[] = array( 'type' => 'LEFT', 'alias' => '', 'table' => 'テーブル名', 'conditions' => 条件, ); ?>
- これで特定の箇所だけ特定のJOINを実行できるはず