使用するのは下記のアセット。
Modern office interior
Japanese Apartment


FPSコントローラーは新しいのを使わなきゃ・・・と思ったら、StandardAssets復活してた!(驚)
MSI02のDドライブ中に、RoomImpressionというプロジェクトとして保存。あとは、照明の種類を変えてやる必要があるだろう。


使用するのは下記のアセット。
Modern office interior
Japanese Apartment


FPSコントローラーは新しいのを使わなきゃ・・・と思ったら、StandardAssets復活してた!(驚)
MSI02のDドライブ中に、RoomImpressionというプロジェクトとして保存。あとは、照明の種類を変えてやる必要があるだろう。


1週間休んですみません。体調を崩し気味で投稿できていませんでした(今もあまりよくはないのですが笑)
pNN50に関連しそうな論文をBingAIに調べてもらったところ
Q:心拍変動のpNN50を用いた論文を5個程度探して
A:心拍変動のpNN50を用いた論文を5個程度探しました。pNN50とは、連続した隣接する心拍間隔の差が50ミリ秒を超える割合のことで、副交感神経の活動を反映する指標とされています。以下は、pNN50を用いた論文のタイトルと概要です。
Q:心理学に関連する論文だとどうかな?
A:心理学に関連する論文を探しました。心拍変動のpNN50は、心理的なストレスや感情 に影響される指標として、心理学的な研究においても利用されています。以下は、心拍変動のpNN50を用いた心理学的論文のタイトルと概要です。
こんな感じに。ほとんどが心拍変動の解説をする資料系の論文で、他も紀要論文やショートレポートのようなもの。・・・あまり国内で研究されていないのだろうか?
少し気になったのは生体計測による自動運転時のドライバの快適覚醒評価と自律神経活動指標を用いた音楽聴取時の精神緩和効果の評価。どちらも本実験と同じ聴覚刺激が関連している。
また、大会発表集の論文まで手を伸ばすと、情報処理学会の大会発表に生体情報に基づく楽器が覚醒度および快・不快度に与える影響の解析やリハビリテーション促進のためのロボットによる声かけ支援、生体情報による感情推定手法とステージの観客反応による評価などでpNN50が用いられている。
こうした論文ではRMSSDの結果が出てこないのだが、RMSSDが比較的新しい解析手法ということを除いてどのような違いがあるかこれもBingAIに聞いてみた。
Q:心拍変動測定時にRMSSDとpNN50の結果がやや異なるとき、どのようなことが言える?
A:心拍変動測定時にRMSSDとpNN50の結果がやや異なるとき、どのようなことが言えるかという質問ですね。RMSSDとpNN50はともに副交感神経の活動を反映する指標とされていますが、計算方法が異なります。RMSSDは隣接するRR間隔の差の2乗の平均値の平方根であり、pNN50は隣接するRR間隔の差が50msを超える割合です1。したがって、RMSSDはRR間隔の差の大きさに、pNN50はRR間隔の差の回数により影響を受けます。例えば、RR間隔の差が50msを超える回数は少ないが、超えるときは大きく超える場合は、RMSSDは高く、pNN50は低くなります。逆に、RR間隔の差が50msを超える回数は多いが、超えるときはわずかに超える場合は、RMSSDは低く、pNN50は高くなります。このように、RMSSDとpNN50の結果がやや異なるときは、RR間隔の差の大きさと回数のバランスが異なることを示していると考えられます。
詳細情報:
1. jstage.jst.go.jp2. trytech.co.jp3. pc-ecg.com4. jstage.jst.go.jp
要は劇的な変化をもたらすわけではないから、RMSSDとpNN50で結果に違いが出たらしい。こうした反応の違いも何かの特徴なのだろうか。
図書館に買ってもらった本に何か載っているか期待してみようと思う。
GPT4にCSV形式の観測データを与え、
「2023年6/9の、AIカメラが捉えたデータです。1列目は時間、2列目はAIカメラに写った顔の数です。3列目以降は無視して良いです。0から23時まで、1時間ごとに、写っていた顔の平均個数を算出してCSV形式で出力して。縦方向に時間が来るように、1列目に時間、2列めに平均個数がくるように、例えば
0,0
1,0
2,0
…
などのように出力してください。」
などとプロンプトすると、結果を出力してくれた。有効データは6/17から7/11までの22日間。全体で平均すると、13-14時、18-21時に顔検出数が大きい結果となった。有効データは8~21時で良いだろうか。さらに、プログラムから当日に提示していたシーンを割り出し、紅葉、海辺、冬山の3種類に分けて描画したところ、学生が自由に活動できる18-21時の間では、冬山>紅葉>海辺の順で顔検出数が多くなった。



各日の18-21時の顔検出数の平均値を求め、提示したシーンにより差があるかを参加者間計画の1要因分散分析で検討したところ、F(2,17)=1.49, n.s.となり、有意な差は認められなかった。

using UnityEngine;
using UnityEngine.SceneManagement;
using System;
public class SceneSwitcher : MonoBehaviour
{
public string[] sceneNames; // 表示するシーンの名前を格納する配列
private int currentSceneIndex; // 現在のシーンのインデックス
private int lastDay; // 最後に確認した「日」
private int lastSecond; // 最後にログを出力した秒
//ここから長野が書き換え231101
private void Update() {
if (Input.GetKeyDown(KeyCode.F12)) { SceneManager.LoadScene("S0"); }
if (Input.GetKeyDown(KeyCode.F1)) { SceneManager.LoadScene("S1"); }
if (Input.GetKeyDown(KeyCode.F2)) { SceneManager.LoadScene("S2"); }
if (Input.GetKeyDown(KeyCode.F3)) { SceneManager.LoadScene("S3"); }
if (Input.GetKeyDown(KeyCode.F4)) { SceneManager.LoadScene("S4"); }
if (Input.GetKeyDown(KeyCode.F5)) { SceneManager.LoadScene("S5"); }
if (Input.GetKeyDown(KeyCode.F6)) { SceneManager.LoadScene("S6"); }
if (Input.GetKeyDown(KeyCode.Escape)) { Application.Quit(); }
}
/*
private void Start()
{
DateTime currentTime = DateTime.Now;
lastDay = currentTime.Day;
lastSecond = currentTime.Second;
currentSceneIndex = lastDay % sceneNames.Length;
//SceneManager.LoadScene(sceneNames[currentSceneIndex]);
}
private void Update()
{
// 現在の時刻を取得
DateTime currentTime = DateTime.Now;
int currentHour = currentTime.Hour;
int currentMinute = currentTime.Minute;
int currentSecond = currentTime.Second;
int currentDay = currentTime.Day;
// 現在のシーン名を取得
string currentSceneName = SceneManager.GetActiveScene().name;
// 秒が変わったときだけ時刻をログに出力
if (currentSecond != lastSecond)
{
lastSecond = currentSecond;
string timeString = currentTime.ToString("HHmmss");
Debug.Log(timeString);
}
// 20:30から7:30までの間はS0を強制表示(ただし現在のシーンがS0でない場合のみ)
//if ((currentHour >= 20 && currentMinute >= 30) || (currentHour <= 7 && currentMinute <= 30))
if ((currentHour > 20 || (currentHour == 20 && currentMinute >= 30)) || (currentHour < 7 || (currentHour == 7 && currentMinute < 30)))
{
Debug.Log("change to S0");
if (currentSceneName != "S0")
{
SceneManager.LoadScene("S0");
}
}
else if (currentDay != lastDay) // それ以外の時間は日が変わったらシーンを切り替える
{
lastDay = currentDay;
currentSceneIndex = currentDay % sceneNames.Length;
if (sceneNames[currentSceneIndex] != currentSceneName)
{
SceneManager.LoadScene(sceneNames[currentSceneIndex]);
}
}
if (Input.GetKeyDown(KeyCode.F12)) { SceneManager.LoadScene("S0"); }
if (Input.GetKeyDown(KeyCode.F1)) { SceneManager.LoadScene("S1"); }
if (Input.GetKeyDown(KeyCode.F2)) { SceneManager.LoadScene("S2"); }
if (Input.GetKeyDown(KeyCode.F3)) { SceneManager.LoadScene("S3"); }
if (Input.GetKeyDown(KeyCode.F4)) { SceneManager.LoadScene("S4"); }
if (Input.GetKeyDown(KeyCode.F5)) { SceneManager.LoadScene("S5"); }
if (Input.GetKeyDown(KeyCode.F6)) { SceneManager.LoadScene("S6"); }
if (Input.GetKeyDown(KeyCode.Escape)) { Application.Quit(); }
}
*/
}
*ゼミの層が他大学よりも薄いため(大学院生が少なく博士もなし),TA関係なく空き時間に授業に出てサポートできると良い.実験参加者も増やせてwin-win.もちろん卒論・就活優先で.
心理サイエンス基礎演習
・前期:UnityでTPS,FPS,Terreinを作成して動画に収める→WebGLが抜けたくらい
・後期:VR開発,Arduinoで簡単な電子回路組立,3Dプリンタ(Cad)
心理サイエンス応用演習
・前期:Fitbit×Python,合成音声,Davinciで動画編集
・後期:STEM教育→科警研の電子回路組立,はんだ付け
*毎年,実施する内容が異なるためなんでもできるようにしておくと安全.授業準備は,基本プロジェクターと電源タップで,後は授業回によって変わる.
3年ゼミ
・卒論の計画を立てて,年始に予備実験や開発が1/3終わってると良い.
・ゼミの雰囲気づくりが大事.
4年ゼミ
・おそくても,6月中旬までに実験が始められると良い.
・8月までに実験データをゼミ生全員が取り終えるように大学院生が調整.
・10月末までに分析を終わらせ,11月中旬に考察と抄録も揃ってると良い.
・大学院生は,卒論のコメントして,提出日まで全員分持ち上げる.
大学院-生理心理学特殊研究
・毎年内容が変わる.受講者数が異なるため.
・M1,2はサポートできたらやるといい.
予備実験が延期になり、データ数が揃うのは11/10の見込みに
空き時間でポリヴェーガル理論で聴覚に関連する部分について調べた。
ポリヴェーガル理論入門(著:ステファン・W・ポージェス 訳:花丘ちぐさ)では、人間は低いピッチの音が捕食動物が近づいて来たと解釈する傾向があり、反対に高いピッチの柔らかい音はお母さんが赤ちゃんをあやす時の声によく見られることから「安全である」という「合図」になりうると触れられている。
特に女性の歌声は低周波を伴わず、抑揚がある上に歌声をコンピューターで変換するとさらに抑揚は強調され音韻も強調されるのでより「安全である」という「合図」を受け取りやすくなるとのことであった。
この際に絡んでくるのが本内で「中耳筋」と呼ばれている部分なのだが、中耳筋という筋肉は少し探した限り見当たらなかった。
中耳というのは鼓膜のさらに先の部分で、鼓膜の他に耳小骨と呼ばれる3つの骨が関節でつながっている部分がある。

この耳小骨の関節を動かす筋肉が本の中で出てきた「中耳筋」と思われる(医学系だと耳小骨筋と呼ばれていた)。これを動かすことで鼓膜の張り具合を変えて聞きたい音を聞き取りやすくするらしい。
さらに、この筋肉をつかさどっている脳の部位が心臓にも関連しているらしい。このため心拍の減少やRMSSDの増加などが見られたのかもしれない。
測定に使ったHTTPFcapはここに紹介されている。







予備実験を1名実施。(のこり3名は水、金、翌月曜に協力してもらう予定)(また、他にも協力して良いとの声があったのでさらに4名増やすか検討したい)
新に取得した結果を加えるとRMSSDとHRのグラフが大きく変わった。1人増えただけなのでカウンターバランスが取れずデータが乱れたのか、はたまた女性の声であればそこまで好感度に差は無いのだろうか・・・?
もう少しポリヴェーガル理論と絡めて調べる必要がある。


一方、皮膚温についてはグラフの上下関係が変わりつつある。枯色がやや下がり、つくよみが少し上がった。


全体的にデータ数がまだ不足気味で何とも言えないが、音声の好感度や性別といった情報で何かしら違いはありそうだ。操作チェックの意味合いも込め、音声の性別や好感度といった情報を被検者から収集した方が良いかもしれない。
合成音声の好感度がリラックス度合にかかわる生理指標にどこまで影響するか、とりあえず予備実験を4名協力していただき、そのデータを概観する
10/24までに3名のデータを取得(内1名の実験中、別のところに気を取られる場面があったのでデータに不安あり、もう一名取るかも・・・)
・結果
皮膚温のデータはあまり変化の無いように思える・・・
RMSSDについては、kybiosの時間設定を間違えていることに気づいたので明日朝修整予定。少し見たところ好感度大と小では被験者内で一貫性があるかもしれない。
まだ順序効果の可能性も捨てきれないため、データの修正と4人目の結果から検討したい。
本日は作業がままならなくなってきたので取り急ぎここまで
はじめに
卒論の実験で取得したデータをもとに, js-starから3要因の分散分析(AsBCモデル)を行っていたところ, 二次の交互作用で有意な差が認められた。しかし, js-starでは二次の交互作用の下位検定が行えなかった。一時は断念したがネットで調べると, js-starのもととなった「R」は下位検定を行うことが可能であった。今回は, Rによる下位検定および使用上の注意点をまとめる。
1. R-4.3.1
・Download:リンク
・js-starとの連携方法:リンク
2. パッケージ
デフォルトでも分析は行えるが入れておくと便利なパッケージを紹介する。パッケージのインストール方法は, 「パッケージ→インストール→Japan→(任意のパックを選択)→ok」を行い, スクリプト画面に「library(パッケージ名)」を入力して漸く使用できる。全体的な操作を通じてPython感があった。
library(Rcmdr):マウス操作で分析を行う
library(sem):Rcmdrのみだとエラー表示のため
library(psych):記述統計量の出力
3. Rの分析方法
ここでは, js-starの算出結果を元に, Rの3要因分散分析の分析方法および結果の見方について紹介する。なお, プログラムはjs-starで発行されたものを使用.
① js-starで分析
通常通りjs-starから分析を実行する。この時,Rオプションの多重比較p値調整法は,Holm法にする(デフォルトではBH法).ページを下部にスクロールさせ「Rプログラム:第1~3枠」のプログラムを用いる。それぞれ「第1枠=主分析」「第2枠=交互作用の下位検定」「第3枠=二次の交互作用の下位検定」を表している。
② Rで実行
Rに移動し, 「library(Rcmdr)」と入力して実行する。その後, Rスクリプト部分に, 先ほどの「Rプログラム:第1~3枠」のプログラムをコピペする。実行する箇所を聞かれるため, ctrl+Aで全選択した後, 実行を行う。すると赤文字でプログラムが書き込まれ, 統計結果は青文字で記載される。また, それに応じた図も表示された。


③ 結果の見方
正直な話, 出力画面に何百行も表示されているが, 第3枠の出力は第2枠も補っているため, 省いていい。また, Rを使用して感動したのが, 統計結果をレポート形式でまとめてくれることだ。つまり, 第3枠の「#結果の書き方」を確認すれば, この長い出力結果と睨めっこしなくていいようだ。下記が出力結果の例である。
一部省略したが, 主効果・一次の交互作用・二次の交互作用の下位検定が確認できる。この記述方法を推奨されているなら, 分析後コピペで済む。めちゃくちゃ楽だ。ただ,多重比較の結果だけは,文章として出力されないためsasのように出力結果を確認する必要がある.また,交互作用の下位検定の有意確率が15%になっているため注意が必要.
==========================================================================
まとめ
Rによる分析方法を紹介したが, js-starを介せば, プログラムも一切不要。また, 統計結果もレポート形式でまとめてくれて, この面のみ見れば非常に便利であった。また, パッケージなどを使用することにより, 上記で紹介した分析ツール以外にも「PDF化, レポート作成, Googleの各種API取得」などできるようだ(サイト)。Rには驚かされてばかりだ…sasよりこっち習いたかったな。
Futurefoxのコットの足が折れること4本目。「保証期間が過ぎたので、オプションパーツを買い求めください」とのことで、2000円かかる。今後も折れる予感がするが、その度買うのはちょっと・・・捨てるしかないのか!?こんな時こそ3Dプリントじゃない!?
PLAで作っても、いかにも折れそうなので、スライサーを設定変更して強化する。外殻(ウォール)は通常2層のところを7層に。TopとBottomの厚みも4ミリに、Infillは80%だ。印刷経過を見てたけど、この設定だと、ほぼほぼ100%詰まってるぞ笑
出来上がったパーツ(印刷時間約2時間)は、ずっしりと重みがある。穴の遊びもまぁ悪くない(純正品と変わらない)レベル。さて、機能するのか!? 写真を取り忘れたけど、ちゃんとコットに組み付けても大丈夫そうだった。「これで足折り放題ですね!(重田)」との事だが、SDGsにはこういう安心感が大事じゃないですか?






M2TP(無線皮膚温測定器)の電池を大容量化した。ケースの下側を再デザインし、850mAhのリチウムイオンバッテリーを内蔵可能とした。ちょっと厚みがあるけれど、6時間程度の動作時間が期待できる。4台作成を試みたけど、4台目は調子が悪いみたいでダメだった。設計ファイルとプログラムも登録し、とりあえず完了。
18:00~
作業内容としては
1.EMG測定器2つの動作チェック
2.配線整理
3.プログラムの修正
(プログラムの修正に関しては長野先生の投稿にて
これで毎度プログラムを書き込まなくて済む・・・)
4.AI測定と同時に実施して、問題点のブラッシュアップ
1.EMG測定器2つの動作チェック
1つめの測定機(大きい方)に関しては問題なし
しかし、0626では使えていたが2つ目の測定器(小さい方)のうち、
片方の測定ができない(画像青部分)

左右を変えて計測しても、プラグを変えても測定不可
配線は手を加えていないので、ボード上の電子機器が接触不良の可能性
2.配線整理
長い配線が計測中にどこかに引っ掛かり、外れる可能性があるので短いものと交換
した
4.AI測定と同時に実施して、問題点のブラッシュアップ
大きい方の計測器とiPadのAI測定を用いて同時に測定をしてみる
配置は図の通り

表情読み取りのiPadとEMG測定器はBluetoothでPCと接続
PCとモニターは有線接続のうえ、2画面のモードにすることで、PC側から動画再生などの操作を可能にした(PC画面はこんな感じ↓)

結果 測定自体は問題なくできることが確認できた
内省報告(兼改善点)
iPadのカメラが下側にあるため高さを稼ぐ必要がある
電極によって頬が引っ張られるような感じがした
PCのポートがほとんど埋まる
Unity の右上に経過時間が表示されるが、他のタブと被って見えなくなってしまった
PolarH10+EliteHRV+Kubiosで心拍変動解析
この組み合わせは、心拍・心拍変動の計測と解析を行う上で、コストパフォマンスの高い優れた方法であると思う。下記動画に大まかな手順を示したので参考にして分析を進めてほしい。
WebCamに現在写っている顔の数を数えてサーバーに保存する
開発場所:CVUnity内、HTTPFcapシーン
OpenCVforUnityのLibFaceDetectionV3Exampleを改造し、検出した顔の情報をWebサーバーに投げて保存するプログラム。今回は測定結果の保存先がWebサーバーであるため、新たにスクリプト「HTTTPrecord」を作成した。データの保存先はここ。アプリケーションのダウンロードはこちらから。
データを受け取るPHPスクリプトは、以下のアドレス。
http://kodamalab.sakura.ne.jp/FaceDetectNum/record.php
データは、「20230608.csv」などのように、日付ファイル名で記録される。記録内容は、検出された顔の数、顔1の信頼性、X座標、y座標、横幅、縦幅、顔2の…といった並びである。
<?php
$data = isset($_POST['data']) ? $_POST['data'] : ''; ; // データをPOSTから取得
if (!empty($data)) {
$date = date('Ymd'); // 現在の日付をYYYYMMDD形式で取得
$timestamp = date('Ymd_His');
$filename = "{$date}.csv";
$file = fopen($filename, 'a');
fwrite($file, $timestamp . ',' . $data . "\n"); // タイムスタンプとデータをファイルに書き込む
fclose($file);
echo "recorded";
} else {
echo "No data!";
}
?>

PolarH10をHRV解析に用いる、低コストで確実な方法はEliteHRVを用いることだ。このソフトウェアはHRVバイオフィードバックを行うためのものであり、iPhone版とAndroid版がある(これ大事)。日本での紹介事例は少ないが、海外では広く使われている。使い方は下の動画を見ればなんとなくわかるが、Polar H10とEliteHRVの組み合わせはとてもすばらしい。
動画では光計測デバイスを用いる例もあるが、指先の血管に伝わってきた拍動情報では心拍変動を正確に評定することは困難であるため、EliteHRVはH10での計測を推奨しており、計測したRR間隔データをExportする方法も提供している。具体的には測定後、ユーザーアカウント部分をクリックし、ExportDataをクリックすると、登録されたメールアドレスに最近計測したデータがメールで転送されるという仕組みだ。出力結果は標準的なRR間隔データで、kubiosにそのまま読み込むことができるので便利だ。
文京学院大学大学院1年の庵袋晴輝と申します。修士論文の予備調査として、音声の印象に関する調査をしています。
ご協力いただける方は下記の手順に従って回答をお願いいたします。
ひとつの音声は30~40秒程度です。
手順
1.下記のFromを表示して質問票を表示してください
フォームへのリンクはこちら
2.音声再生ページを下記のリンクから表示してください。
音声再生ページへのリンクはこちら
3.下記のように、印象評定ページと音声再生ページを並べた状態で評価を行ってください。再生する音声の順序は、参加者によってランダムになっているため、Formsに表示された順序で上から順番に8種類を評定してください。
音声は回答ができるなと感じたところで再生を止めていただいても構いません

Apple ARkitのアドバンテージは?
MediaPipeのFacemeshを使って、「・・・コレ大丈夫か?」と思ったのは事実。推定されたMesh位置情報を高速でサンプルして描画すると、激しいノイズが。メッシュの推定がブレているということだ(見た目にもそんな予感はしていた)。顔の姿勢取得も苦労したが、そもそも2/15の記事で、ARkitの方は眼球の姿勢がとれていた(当然顔の姿勢もとれるだろう)。
改めてARkitの顔認識をよく見ると、(こんなに暗いのに)ものすごくピッタリ推定できており、口の動作もほとんど完璧だ(Mediapipeは横向くと推定が怪しくなり、口も勝手に開いたりする)。google vs apple、IT界の両雄が作る似たサービス、同じくらいのクオリティがあると思ったら間違いで、おそらくこれに関してはARkitの圧勝だ。・・・自分は今、岐路に立たされている。Appleの軍門に下る事(あるいはApple製品を新たに購入するコスト)を避け、Mediapipeで実装すると、AIによる顔認識研究のクオリティは下がり、僕の評判も悪くなるだろう。「ここは買っとけ、iPad買っとけ!」・・・私のゴーストがそう囁くので、ケチケチせずiPadを2つ購入しようと思う。今、AI非接触計測の経験値を高めておけば、きっと何十倍にもなって返ってくる(ハズ)。このような実践で鍛えられた「◯◯のような用途にはこのAIが使える」といった細かな経験値が、今後数年はモノを言う気がする。
iPadのARkit対応状況はこちらのサイトにまとめられている。2019年のモデルあたりから使えるみたいだけれど一番安いのはどれかな。iPad Proは高機能だけれど2つ買うのは絶対嫌だし、ひょっとして2021年モデル(64GB)が43000円というのは、「買い」なのではないだろうか!?自腹なら中古でiPhoneという手もあるが、\24800のいつ壊れるかわからないXsを購入するのは危険に思える(実際壊れたXsが手元にひとつあるわけだし)。
Blendshapeを取得する
そして確認されるBlendshape。これはあくまでBlendshape値なので、顔の動きそのものではないが、運用上はこのほうが都合が良い。お笑いを見せて、一番動きが大きなBlendshapeを笑いの評価に使うとか。。。大頬骨筋に比べると、皺眉筋の動作検出は弱いように思える。用途の問題なのか、そもそも動く量が少ないからか。数値的にはEMGのアドバンテージは確定的にも思えるが・・・。
皺眉筋、大頬骨筋、上唇挙筋などに対応したブレンドシェイプがあるように思える。いろいろな動画刺激に対して、これで感情評価を行えば良い。ipadをどう固定するか考えないとね。
ChatGPT対抗手段として、とうとうリリースされたのがGoogleの大規模言語AI「Bard(吟遊詩人?)」である。どうやってPythonから使うのかな?・・・なんかBardに教えてもらった方法で、できないんだけど・・・
PythonでBardを使う例(230516)
BardAPIて?
あ、こちらでも解説されていますね
BardAPI本家 すばらしい・・・
GPTとBardで意思決定 自己採点のアイデアが良い。互いに採点もできるの!?
GPTとBardに概念を考えてもらう プロンプトが参考になる
・・・そして完成するBradとの会話プログラム。BradAPIを使っています。APIkeyは、ブラウザのクッキーから取得するという手順。これでいいんだろうか?・・・やはり現在の情報が参照できるのはアドバンテージありますね。しかし、推論の妥当さなどはGPT3.5や4にアドバンテージがあるように思う。どのような実装にすべきか、悩みますね。Unityから呼び出す方法は、まだ解説されていないようだし。
from bardapi import Bard
import os
os.environ['_BARD_API_KEY']="hogehoge."
def main():
print("チャットをはじめます。q または quit で終了します。")
print("-"*50)
while True:
user = input("<あなた>\n")
if user == "q" or user == "quit":
print(f"トークン数は{amount_tokens}でした。")
break
else:
#chat.append({"role": "user", "content": user})
msg=Bard().get_answer(user)['content']
print("<Bart>")
print(msg)
if __name__ == "__main__":
main()

現状・・・調べ物にはBardがいいけど、人格ドライブにはGPT3.5がいいように思える。Bardに協力してもらおう!
#サイト上のcommandをチェックしBardでanswerに問い合わせ結果を書き込むスクリプト
from bardapi import Bard
import os
import time
import requests
os.environ['_BARD_API_KEY']="ほげ"
command_url = "http://kodamalab.sakura.ne.jp/AIchat/Bard1/command.txt"
response_url = "http://kodamalab.sakura.ne.jp/AIchat/Bard1/response.php"
#ファイルサイズを得る
def get_file_size(file_url):
response = requests.head(file_url)
try:
return int(response.headers['Content-Length'])
except KeyError:
return None
#コマンドの内容を得る
def get_command(file_url):
response = requests.get(file_url)
response.encoding = 'utf-8'
return response.text.strip()
#Bardからの回答を保存する
def write_response(response_url, response_text):
data = {'response': response_text}
requests.post(response_url, data=data)
answer=""
last_size = get_file_size(command_url) or 0
while True:
current_size = get_file_size(command_url) or 0
print("." , end=' ')
if current_size != last_size:
command = get_command(command_url)
print(f"<COMMAND>{command}")
answer = Bard().get_answer(command)['content']
print(f"<ANSWER>{answer}")
write_response(response_url, answer)
last_size = current_size
time.sleep(2) # wait for 5 seconds before checking again
c#から呼び出す方法
解説されているが、アラビア語で理解できないという。コードを見れば・・・わかるよね?
・・・このコードは、UnityではないC#用で、LinqやThreadingなどの新しい手法を用いており、いまいち何をしているのか理解できない。エラーも出ているようだし・・・。とりあえずすべて打ち込んで、GPT4に解説してもらう。
コード1(Bard_Serviceクラス)とコード2(BardResponseModelおよびResultクラス)は、Googleの大規模言語モデルBardのAPIに接続して問い合わせを行うためのクラスです。
コード3は、これらのクラスを使用して実際に問い合わせを行うためのコードです。具体的には、エジプトの面積について問い合わせています。
以下に、各コードの詳細な説明をします。
コード1(Bard_Serviceクラス)
このクラスは、Googleの大規模言語モデルBardのAPIに接続し、問い合わせを行うためのサービスクラスです。
apikeyとendpointは、Bard APIへの接続情報を保持します。
Bard_Service(string apikey, string endpoint)は、コンストラクタで、APIキーとエンドポイントをセットします。
AskBard(string prompt)メソッドは、引数として渡されたプロンプト(問い合わせ)を用いてBard APIにPOSTリクエストを送信し、その応答を返します。成功した場合は応答の内容を返すべきですが、現状では成功した場合の処理が不足していて何も返していません。失敗した場合は例外をスローします。
コード2(BardResponseModelおよびResultクラス)
このクラスは、Bard APIからの応答をデシリアライズ(文字列からオブジェクトへの変換)するためのモデルクラスです。しかし、コード1の現在の状態では、このモデルクラスは使われていません。
コード3(Programクラス)
このクラスは、上記のサービスクラス(Bard_Service)を使って、Bard APIに問い合わせを行うメインのプログラムです。
BARD_API_ENDPOINTは、Bard APIのエンドポイントを保持しています。
Mainメソッドでは、Bard_Serviceクラスのインスタンスを作成し、そのAskBardメソッドを呼び出してBard APIに問い合わせを行い、その結果をコンソールに出力します。
ただし、現状のコードでは、問い合わせが成功した場合の処理が不足しているため、問い合わせの結果を正しく取得して出力することはできません。これを修正するには、コード1のAskBardメ
すみません、切れてしまいました。
AskBardメソッド内で、成功した場合の結果(result)を適切に返すように修正する必要があります。つまり、以下のように修正すべきです:
public async Task<string> AskBard(string prompt)
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(endpoint),
Content = new StringContent(prompt,Encoding.UTF8, "application/json")
};
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apikey);
using (var response = await client.SendAsync(request))
{
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result; // 追加:成功した場合には結果を返す
}
else
{
throw new Exception("Request failed with status code "+ response.StatusCode);
}
}
}
なお、Bard APIからの応答は通常JSON形式であり、コード2に示されたBardResponseModelクラスを用いてデシリアライズすることを想定しているように見えます。したがって、より完全な実装では、応答をこのクラスにデシリアライズし、その結果を返すようにすべきでしょう。それには、たとえばSystem.Text.Json.JsonSerializerを使用することができます。
最後に、ProgramクラスのMainメソッド内では、AskBardメソッドが非同期(Taskを返す)であることを考慮し、その結果を適切に取得するようにする必要があります。具体的には、.Resultまたは.GetAwaiter().GetResult()を使用して結果を取得するか、Mainメソッド自体を非同期にしてawaitを使用することが考えられます。
ふむふむ・・・やはりコード自体も未完成のようだね。UnityでCoroutineをつかう形式に書き換えてもらおうか。・・・うーむ、そもそもこのコード呼び出し用URLもNotFoundだし、正しく動作しない気がする。一旦保留しようか。
・・・BartAPI本家に、Python他言語に移植したソースが昨日公開されていた。CSもあったが、UnityはフルCSじゃないから、GPT4にUnity対応してもらったのが下コード。コレが動けば、Bart関係の処理が盤石になるな。
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.Networking;
public class Bard : MonoBehaviour
{
private const string BARD_URL = "https://bard.google.com/_/BardChatUi/data/assistant.lamda.BardFrontendService/StreamGenerate";
private string token = "your bard token";
private int reqId;
private string conversationId;
private string responseId;
private string choiceId;
void Start()
{
this.reqId = new System.Random().Next(1000, 9999);
this.conversationId = "";
this.responseId = "";
this.choiceId = "";
StartCoroutine(GetAnswer("input text here"));
}
private IEnumerator GetAnswer(string inputText)
{
Dictionary<string, string> headers = new Dictionary<string, string>
{
{ "Content-Type", "application/x-www-form-urlencoded;charset=UTF-8" }
};
headers.Add("Cookie", $"__Secure-1PSID={this.token}");
WWWForm form = new WWWForm();
form.AddField("bl", "boq_assistant-bard-web-server_20230419.00_p1");
form.AddField("_reqid", reqId.ToString());
form.AddField("rt", "c");
// to be filled out with correct data serialization
form.AddField("f.req", $"[null, []]");
form.AddField("at", "SNlM0e"); // to be filled out with correct SNlM0e value
using UnityWebRequest www = UnityWebRequest.Post(BARD_URL, form);
foreach (KeyValuePair<string, string> entry in headers)
{
www.SetRequestHeader(entry.Key, entry.Value);
}
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success)
{
Debug.Log(www.error);
}
else
{
// TODO: Process the response, similar to the GetAnswer method
Debug.Log(www.downloadHandler.text);
}
}
}