見出し画像

実験! 進化思考 / 名著 進化思考のLogicを 実験で確かめる(その8:蛇の道と知りつつ、生成AIで 「進化のタイパ」 を遂行する)

いったい 何してたん!?

実に 4ヶ月ぶりの投稿です。
その間、何をしていたのか…
実は サボっていた と言うより 色々試行していたのですが、中々 公表する様な成果に結び付かず、あれよあれよ… という間に 時間が過ぎてしまいました。😵‍💫

色々とは…
最初のつまずきは、シリーズ その5 まで展開していた 粘菌解析では 色々 計算方法を探索したのですが、ついに 適正な解(=条件により 最適なルートを自動探索する)を見つけられずに断念。 😱
その為、その6で開示しようとしていた プログラミング公開を諦めました。

次に着手したのは、進化テーマを Wikipedia上から 進化思考・時空間マップにおける 解剖/生態/歴史/予測 の情報を抽出するプログラム。
これは、「Wikiから抽出した情報を元に 生成AI(LLM)を使って 文章化する」ものであり、そこそこ出来たのですが、良く考えると 生成AIの餌(元データ)として Wikiは使われているので、いっそ 直接 生成AIに問い合わせた方がスマートじゃん! という無駄な遠回りをした結果、4ヶ月も過ぎてしまいました。 🥴

とは言え、お陰様で プログラミングの感覚を少し思い出し、開発環境にも 少し慣れてきたので ここまでの成果公開をします。

何を作ったんですか?

前述の通り、「進化テーマを (Chat)GPTに投げ込んで、進化思考・時空間マップにおける 解剖/生態/歴史/予測 の情報を抽出するプログラム」になります。
出来上がりは こんな感じ。

時空間マップ: 「自動車」の例

この例ですと、ユーザは 「自動車」と入力するだけで、(環境にも依りますが)約50秒くらいで このマップが出来上がります。
このシリーズの初回(その1)で 「生成AIは 進化(思考)にあらず」とブチまけていた割には こんなものを作って 蛇の道に手を染めている感は否めませんが、これも 時代には逆らえず/逆らわず… という事で、圧倒的な 時短/タイパの効果を優先しましょう。

もちろん、進化思考を学ばれた方は 御存知の通り、これは あくまでも "準備段階" であり、進化思考の真骨頂は「"ここから/これをベースに" あらゆる方向への進化を思考する」 ものなので、あくまでも 「進化の準備の為の 時短ツール」になります。

どんな仕組み?

プログラムの仕組みは 至って簡単です。

  1. 必要なモジュールを呼び出し、下準備。

  2. 進化テーマを入力。

  3. GPTに投げ込む 質問文を作成。

  4. 出力準備。 今回は 予め用意した 時空間マップの画像データに 貼り付ける形とした。(なので、抽出した文字も "画像形式"での貼り付け になります ← コピペが出来ないので ここは 後日 改良します)

  5. 解剖/生態/歴史/予測 の4つの質問に対する解答を 所定の画像位置に貼り付け

  6. 最後に 進化テーマを 画像中央に 貼り付けて 画像出力。

簡単です。 😃
誰にでも作れます。 もしかしたら 既に 作った方もおられるかも。

強いていうと 質問文を それらしく作る所が ミソ(コツ)でしょうか。
詳細は 後ほど…

ざっくり解説

言語は Pyrhon。 環境は Google Colab。 LLMは Open-AI を使用 の事例になります。

  1. 下準備

Open-AIは 予め アカウントを作成し、API-Key を取得し、Google Colab のシークレットキーに 設定しておく必要があります。
PILは 画像埋め込み用のモジュール のインポート。

"sw_GPT" は、質問を投げ込む GPTモデルの選択で、本プログラム内部設定用の変数(定数)です。

# ***** 下準備 *****
!pip install openai

from openai import OpenAI
import os
from google.colab import userdata
from PIL import Image, ImageDraw, ImageFont

os.environ["OPENAI_API_KEY"] = userdata.get('OPENAI_API_KEY')
client = OpenAI()

# GPTのモデル選択
sw_GPT = "V4"
# sw_GPT = "35-turbo"

# 画像Path指定
os.chdir("/content/drive/MyDrive/Colab Notebooks")
path = os.getcwd()

# 画像名指定
image_path = "image/baseSheet_2.jpg"
output_path = "image/output_image.jpg"

# フォント指定
font_path = "Fonts/「お好きなフォント」.ttc"
font_size = 14

その後、 画像ファイルの指定、フォントの設定、出力画像の"下地"の画像を読み込み を行います。 

OSの機能を使って Path(カレントフォルダ)を指定し、入出力画像ファイル名を指定します。 
この例ですと カレントフォルダに "image" フォルダを作成しておいて下さい。  

フォントは、日本語で出力したい場合は(当然)日本語フォントを指定下さい。 
Google Colab 環境では デフォルトでは 綺麗な日本語フォントは設定されていない(かな?)と思いますので、自分の Driveに 好きなフォントを Copyして読み込みます。 
下記の記述例ですと、カレントフォルダに "Fonts" フォルダを作成し、その中に「お好きなフォント」データを Copyしておき、そのファイル名を指定します。(コードの「お好きなフォント」部分を書き換えて下さい) 

ちなみに、Windows用のフォントも Copyして使える様ですが、ライセンス的に許容されるか? は 御確認下さい。

2.進化テーマを入力
 特に関数化する事も無いですが…
(関数名は 改造経緯の名残ですので 気にせずに…)

# 進化テーマの入力関数
def find_relation_patterns():
  word1 = input("\n *進化させたいテーマ(単語)を入力してください。:")
  return word1

3.GPTに投げ込む 質問文を作成
まずは、先程の関数を使って "進化テーマ"を入力します。

  それを使って GPTに投げ込む質問文のリストを作成します。 
  全部で 4行。 1行目から 歴史/解剖/生態/予測 用の質問文になります。
  "word" は、2.項 で入力した 進化テーマが代入されます。

  前述の通り、ここの内容により 出力結果が(大きく)影響を受けます
  ので、いい感じの文を試行錯誤してみて下さい。✨

# 探索語 入力
word = find_relation_patterns()

# 質問文作成用のリスト
list_question = [
  word + "の歴史に関して 箇条書きにして まとめて下さい。 進化の過程が判る様に説明して下さい。",
  word + "の構造に関して 箇条書きにして まとめて下さい。 どんな仕組みで成り立っているのか いくつかの部品に分けて説明して下さい。",
  word + "に関連する事項に関して 箇条書きにして まとめて下さい。 "+ word + "と共に進化をしている事や "+ word + "によって影響を受けている様な事を説明して下さい。",
  "これらの情報から" + word + "の未来を予測して下さい。 皆がワクワクする様な進化して行く様を 箇条書きにして下さい。"
]

4.出力準備
 時空間マップの下地画像は、Excelで作成した物を jpeg形式で保存しました。
 時空間マップのフォーマット自体には(太刀川さんの)版権は 掛かっていない(?)かと思いますので、下記に置いてみます。(NG情報が有れば 御連絡を!)
カレントフォルダに "image" フォルダを作成し、そこに Copyして下さい。

5.解剖/生態/歴史/予測 の4つの質問に対する解答を 所定の画像位置に貼り付け
 いよいよ メイン部分です。
 冒頭の 2つの関数は、解答を得る関数と 解答のテキスト文を画像に貼り付ける関数です。

# 質問に対する解答を得る関数
def ask_question(question):
  prompts = f'''以下の質問に対し、回答して下さい
  [ユーザの質問]
  {question}
  '''

  if sw_GPT == "V4":
    response = client.chat.completions.create(
      # model = "gpt-4o",
      model = "gpt-4o-mini",
      messages = [{"role": "user", "content": prompts}],
      # prompt = prompts,
      max_tokens = 500
    )
    return response.choices[0].message.content

  else:
    response = client.completions.create(
      model = "gpt-3.5-turbo-instruct",
      prompt = prompts,
      max_tokens = 300
    )
    return response.choices[0].text


# 解答を画像に貼り付ける関数
def add_text_to_image(draw, text, position, font_path, font_size, text_color):
  # フォントを設定
  font = ImageFont.truetype(font_path, font_size)
  # テキストを描画
  draw.text(position, text, font=font, fill=text_color)


# 出力用画像を開く
with Image.open(image_path) as img:
  # 描画オブジェクトを作成
  draw = ImageDraw.Draw(img)


# 解答探索(メイン部分)
for i, question in enumerate(list_question):
  answer = ask_question(question)

  # 記載位置、色指定
  match i:
    case 0:
      position = (900,920)  # x, y座標 / 歴史
      text_color = (0, 128, 128)  # RGB形式 (この例ではCyan色)
    case 1:
      position = (100,550)  # x, y座標 / 解剖
      text_color = (0, 128, 0)  # RGB形式 (この例では緑色)
    case 2:
      position = (1800,550)  # x, y座標 / 生態
      text_color = (128, 0, 128)  # RGB形式 (この例ではピンク色)
    case 3:
      position = (900,170)  # x, y座標 / 予測
      text_color = (0, 0, 255)  # RGB形式 (この例では青色)

  text = answer

  # 空白行削除
  while '\n\n' in text:
    text = text.replace('\n\n', '\n')
  print(text)

  # 1行の文字数を制限する
  line = 90
  output=""
  cnt=0
  while cnt < len(text):
    if (cnt + line) < len(text):
      output += (text[cnt : cnt+line] + "\n")
    else:
      output += (text[cnt : len(text)] + "\n")
    cnt += line

  # 画像に貼り付け
  add_text_to_image(draw, output, position, font_path, font_size, text_color)

冒頭の sw_GPTの定数は GPTの種類を指定するものです。
デフォルトでは GPT-4o。 "-mini" をつけて mini版でも ちゃんとした解答が得られています。
(無いとは思いますが)GPT-3.5 Turbo にしたい場合は sw_GPTを "4V以外" にして下さい。 (4oと 3.5 では I/Fに違いが有るのがお解りかと…)

"max_tokens" 変数は、GPTから返ってくる解答の長さになります。
長い方が 情報量が多くなりますが、多過ぎると 画像からハミ出てしまいます。

add_text_to_image は 所定の位置に 文字列を 画像に貼り付ける関数です。

出力用の画像を Openした後、
# "解答探索(メイン部分)" 以下が 作成した質問文を GPTに投げて 解答を得るメインループです。
3. で作成した 質問リストに従い、歴史/解剖/生態/予測 の4回 ループします。

ask_question関数で 質問に対する解答を得ます。
その後、画像に貼り付ける"位置" を指定した後、
見栄えを良くする為に 空白行の削除と 1行の文字数制限をかけます。
(何故か 空白行が 完全に消えない…)
(貼り付ける位置は 下地の画像サイズや デザインを変えると 修正が必要になります。)

下地画像への 文字の貼り付けは、add_text_to_image関数で行います。

6.進化テーマを 画像中央に 貼り付けて 画像出力
最後に "進化テーマ" を中央に貼り付けた後、画像を jpeg形式で出力します。
出力画像は image フォルダに 固定名で "output_image.jpg" と出力されます。

出来上がりの確認は このファイルを ダウンロードして Viewerで 御確認下さい。

# 中央に 検索文言を貼り付け
position = (1100,770)  # x, y座標
text_color = (0, 0, 0)  # RGB形式 (この例では黒色)
font_size = 40
text = word
add_text_to_image(draw, text, position, font_path, font_size, text_color)

# 結果を保存
img.save(output_path)

【Excuse】
(1) LLMから返ってくる解答が 文章の途中で終了してしまうケースが有ります。 この制御方法(キッチリ 文末で終了する)が判らないので、中途半端な結末になる事が有ります。(この点は 御容赦下さい)

(2) このソースコードは あくまでも参考用のソースです。
  このソースコードの一部 もしくは 全文の活用による 障害・著作権問題 等、あらゆる社会的問題に関しては 当方では 対応出来ませんので 御理解の程をお願い致します。
 *御指摘事項が有れば 御連絡下さい。問題部分の削除で対応させて頂きます。

その他の出力サンプル

進化テーマ=「京都」
進化テーマ=「地球」

気になったら お試し下さい!
また お気付きの点が有れば 御指摘下さい。
ソースコードは どこかで GitHubで 公開する様にします。

この記事が気に入ったらサポートをしてみませんか?