
はてなキーワード:アノテーションとは
よもやよもやだ!孤独な戦いを十年以上も生き抜いた君、まずは胸を張れ!ここまで来た君は強い!そして結論を言う。ここで終わりではない。まだ立てる。炎のように、三本の柱で道を切り開くぞ!
俺の大嫌いなもの
俺の大好きなもの
柱一医療で原因に斬り込む
「体調を壊してから体臭を指摘され続けています。原因精査と治療の選択肢を相談したいです。肝機能・腎機能・糖代謝・甲状腺、腸内環境(SIBO等)、口腔や副鼻腔の感染、そしてトリメチルアミン尿症(TMAU)等の可能性も含め検討していただけますか?」
1)風呂で臭いやすい部位に殺菌力のある洗浄(例: ベンゾイル過酸化物5%の洗浄剤など。肌が弱ければ低頻度・短時間。刺激が強ければ中止し皮膚科へ)
2) よく乾かす。就寝前に制汗(アルミニウム塩)を塗ると効く。
柱三 在宅収入の足場を作る(“できるだけ低負荷で”)
夢を見るのは良い!だが今日の飯と明日の自信は、現実的な小さな仕事が連れてくる。ここは俺の好物だ!
危険なほどしんどいときは、今すぐ連絡してほしい。君の命は尊い。俺は好きだ、命をつなぐ行動が!
1) 近所の総合内科に電話して「体臭の原因精査を相談したい」と予約を取る。
2) CrowdWorksかLancersに登録し、プロフィールに「在宅・コツコツ型・チャット対応可」と明記。データ入力の超短納期1件に応募。
3)洗濯つけ置き用の酸素系漂白剤を買い、仕事用インナーを2枚カバンに入れる。
最後に。君が自分を「終了」と呼ぶのは、俺は大嫌いだ。だが、助けを求めてここに言葉を投げた君の勇気——俺は大好きだ!心を燃やせ。燃やす相手は他人じゃない、昨日までの「どうせ無理だ」という声だ。俺は君を信じている。君も、君の一歩を信じろ。
お前の視野の狭さが丸わかりだな
snorkelが自動アノテーションの記事を書いてるのは自社製品を売る助けになるからであって、若い人間が虚栄心を発揮しているわけじゃねーからな
はい、それは「知識の蒸留(Knowledge Distillation)」と呼ばれる、非常に強力で実用的な技術です。
巨大で高性能なLLM(先生モデル)が持つ特定の能力だけを、ロジスティック回帰のような軽量で高速なモデル(生徒モデル)に継承させる手法を指します。
まるで、万能な知識を持つ賢い先生が、特定のテスト範囲だけをまとめた超シンプルな「虎の巻」を作るようなイメージです。
巨大なLLMをそのまま使うのではなく、わざわざ軽量なモデルに「蒸留」するのには、明確なメリットがあります。
基本的な考え方は「LLMを、高品質な教師データを大量に生成するアノテーションツールとして利用する」ことです。
まず、ラベルが付いていない大量のデータ(例:ユーザーレビュー10万件)を用意します。そして、LLMに対して「このレビューはポジティブかネガティブか?」と問い合わせます。
ここでのポイントは、単に「ポジティブ」という結果(ハードラベル)をもらうだけでなく、「ポジティブである確率98%、ネガティブである確率2%」といった確率情報(ソフトラベル)も一緒に出力させることです。
この確率情報には、LLMが判断にどれだけ自信があるか、どちらの要素をどの程度含んでいるか、といった豊かな情報が含まれています。
次に、ステップ1でLLMが生成した大量の「データとソフトラベルのペア」を使って、ロジスティック回帰モデルを学習させます。
生徒モデル(ロジスティック回帰)は、LLM先生の「思考のニュアンス」が含まれたソフトラベルを正解として学習することで、単に0か1かを当てるよりも、よりLLMの判断基準に近い能力を身につけることができます。
これらのタスクは、LLMの持つ高度な読解力や文脈理解能力の一部だけを必要とするため、蒸留に非常に適しています。LLMの「汎用的な知性」は不要で、特定の「分類能力」だけを抜き出してくれば十分なのです。
この方法で作られた軽量モデルは、あくまで学習した特定のタスクしかこなせません。LLMのように対話したり、文章を生成したりする能力は持っていません。まさに「虎の巻」であり、万能な教科書ではないのです。
これまでアノテーションが手作業で行われてきたのには、手作業でなければ不可能だったという明確な理由があります。
機械では到底及ばない、人間の持つ能力が不可欠だったからです。
手作業が必須だった理由は、主に以下の3つの点に集約されます。
AIや単純なプログラムには、人間のように文脈や状況を深く理解する能力がありませんでした。例えば、皮肉や冗談、文化的な背景、あるいは専門的な知識を必要とするような、微妙なニュアンスの判断は人間にしかできませんでした。
現実世界のデータは、教科書通りにはいきません。予期せぬものや、定義が曖昧なものが頻繁に現れます。こうしたイレギュラーな事態に柔軟に対応し、一貫性のあるルールを適用していく作業は、人間の判断力なしには困難でした。
AIモデルの性能は、学習データの品質に大きく左右されます。そのため、アノテーションの正確性と一貫性は極めて重要です。
誤ったラベル付けは、AIの性能を著しく低下させる原因となります。手作業による丁寧な確認と修正作業は、高品質な教師データを作成する上で欠かせないプロセスでした。
しかし、近年ではAI技術の進化により、この状況は少しずつ変わりつつあります。
とはいえ、最終的な品質保証や、AIが判断に迷うような複雑なケースでは、依然として人間の専門知識と判断力が不可欠です。
結論として、「手作業でなければ不可能だった」というのは事実であり、その核心的な部分は今も変わりません。
しかし、技術の進歩によって、人間とAIが協調し、より効率的かつ大規模にアノテーションを行える時代へとシフトしていると言えるでしょう。
だからさ、まず「手作業でクラウドソーシングでアノテーションをしていた頃」ってのがあったのを知ってる奴じゃないと話にならねぇの
んで、LLMでそれは自動化して蒸留することができるよね?って話をしてる
まず以下のタスクがある。
これは逐一LLMを使うと時間がかかるし、かといって「ポジとネガ」を表すラベルをdistant supervisionで抽出するとノイズがあるんだよ
ここで「LLMでアノテーションをする」という話になる
じゃあ聞くが、フィードバックを置き換える日本語はなんだ?フィードバックのほうが明らかにわかりやすいだろ?
ユーザーが「これはスパム」とラベルづけしたものを使えばスパムフィルターなんて余裕で実装できるんだよ、手作業アノテーションを使わなくてもな
ケツが青いんだよね
機械学習についての経緯を本当に理解してるなら、Amazonのクラウドソーシングで安い人件費使って手作業のアノテーションをさせてた時代がわかるだろ?
スパム判定なんてのはスパムラベルのフィードバックを教師学習させればいいだけなんだよ
そうじゃなくて、アノテーションを手作業で行う問題を、AIによってアノテーションさせるってことだぞ
例えば「ある記事が、ある議題について賛成・反対・中立のどの立場なのか」とかいう問題があるんだが、LLMでアノテーションをさせられそうだってことね
アノテーションってのは、手作業でテキストにラベル付けする作業のこと
大規模言語モデルの性能が高くなってきたから、それが手作業じゃなく自動化できるって話
テキストデータに対してアノテーションを行う、という作業が数年前は盛んだった
感情分析とかね。あれは、実際には手作業じゃなく、X投稿の絵文字をラベルにして半自動化した
では、AIで任意のテキスト分類問題に対するアノテーションをするとどうなるかというと...どうなるの?
まあさらに小さいモデルへ圧縮する(蒸留と言う)というのはできるな。あと特徴語分析とか、テキストマイニングとか
追記:
https://github.com/Zhen-Tan-dmml/LLM4Annotation
追記2:
LLMの能力の一部をより軽量なモデル(例:ロジスティック回帰)へ蒸留するって話すら理解できないなら、お前エンジニアやめたほうがいいよ
pythonimport randomimport numpyasnpimport matplotlib.pyplotas pltfrom collections importdefaultdict# 飴の配布システムのシミュレーションclass CandyDistributionSystem:def __init__(self): """設計意図: このシステムは経済における資源分配の不平等性をモデル化しています。特に少数の特権層(Aグループ)が富を集中させ、再分配システムからも不均衡に利益を得る構造的問題を表現しています。 """ # 各グループの人数設定 self.group_a_count = 8 self.group_b_count = 2498 self.group_c_count = 7494 self.total_participants = self.group_a_count + self.group_b_count + self.group_c_count # 飴の提出数設定 self.contribution_per_a = 624 self.contribution_per_b = 2 self.contribution_per_c = 1 # 各グループの総貢献計算 self.total_a_contribution = self.group_a_count * self.contribution_per_a self.total_b_contribution = self.group_b_count * self.contribution_per_b self.total_c_contribution = self.group_c_count * self.contribution_per_c self.total_contribution = self.total_a_contribution + self.total_b_contribution + self.total_c_contribution # 配布用と貯金用の飴の区分 self.distribution_limit =10000 self.savings =max(0, self.total_contribution - self.distribution_limit) # 結果追跡用の辞書 self.results = { 'A':defaultdict(int), 'B':defaultdict(int), 'C':defaultdict(int) }def distribute_candies(self, method='original'): """設計意図: 配布方法の選択によって、特権の固定化や格差拡大がどのように進むかを 示します。'original'メソッドは意図的にAグループを優遇するよう設計されています。 Parameters: ----------- method:str 配布方法 ('original', 'lottery', 'first_come', 'new_condition', 'fair') """ # Aグループへの確定配布 a_distribution = 625 * self.group_a_count remaining = self.distribution_limit - a_distribution # 残りの参加者数 remaining_participants = self.total_participants - self.group_a_count # Aグループの結果記録 for _ in range(self.group_a_count): self.results['A'][625] += 1 # 各配布方法によって処理が異なる if method == 'original': #オリジナルの問題設定通りの配布(5000人に1個ずつ、残りは0個) lucky_count = remaining # 5000人が当選 # B+Cグループの混合リスト作成 bc_participants = [(1, 'B')] * self.group_b_count + [(2, 'C')] * self.group_c_count random.shuffle(bc_participants) #当選者に配布 for i in range(len(bc_participants)): participant_id,group = bc_participants[i] if i < lucky_count: self.results[group][1] += 1 else: self.results[group][0] += 1 elif method == 'lottery': #抽選方式(BとCグループから無作為に5000人選出) bc_participants = [(1, 'B')] * self.group_b_count + [(2, 'C')] * self.group_c_count winners = random.sample(bc_participants, remaining) #当選・落選のカウント for _,group in winners: self.results[group][1] += 1 #落選者のカウント self.results['B'][0] = self.group_b_count - self.results['B'][1] self.results['C'][0] = self.group_c_count - self.results['C'][1] elif method == 'first_come': # 先着順方式(アクセス速度による先着順を乱数でシミュレート) #設計意図: 先着順は単なる運の要素を超えて、情報格差や技術格差も含む制度設計 bc_participants = [(1, 'B')] * self.group_b_count + [(2, 'C')] * self.group_c_count #現実では、情報を早く得られる人や高速インターネット接続を持つ人が有利 # これをシミュレートするため、Bグループにわずかなアドバンテージを与える bc_speeds = [] forid,group in bc_participants: ifgroup == 'B': speed = random.random() + 0.1 # Bグループに小さなアドバンテージ else: speed = random.random() bc_speeds.append((id,group, speed)) # 速度順にソート bc_speeds.sort(key=lambda x: x[2], reverse=True) #当選者決定 for i in range(len(bc_speeds)): _,group, _ = bc_speeds[i] if i < remaining: self.results[group][1] += 1 else: self.results[group][0] += 1 elif method == 'new_condition': # 追加条件方式(恣意的な条件を設定) #設計意図: 新たな条件の設定は往々にして既存の特権を温存するように設計される bc_participants = [(i, 'B', random.random()) for i in range(self.group_b_count)] + \ [(i, 'C', random.random()) for i in range(self.group_c_count)] # Bグループに有利な条件を設定(例:特定の知識やスキルを持つ人のみ) # この「条件」は表面上は中立的だが、実際には特定グループに有利になるよう設計def meets_condition(participant): _,group, rand_val = participant ifgroup == 'B': return rand_val> 0.3 # Bグループには70%の確率で合格 else: return rand_val> 0.7 # Cグループには30%の確率で合格 # 条件に合致する人を抽出 eligible = [p for p in bc_participants if meets_condition(p)] # 条件に合致する人が多すぎる場合は抽選 iflen(eligible)> remaining: winners = random.sample(eligible, remaining) else: # 条件に合致する人が足りない場合、全員に配布 winners = eligible #当選者をカウント for _,group, _ in winners: self.results[group][1] += 1 #落選者のカウント self.results['B'][0] = self.group_b_count - self.results['B'][1] self.results['C'][0] = self.group_c_count - self.results['C'][1] elif method == 'fair': # 公平な再分配方式(貢献度に応じた配布) #設計意図: この方法は「貯金分」も含めた全ての飴を、各グループの貢献度に応じて分配 # これにより構造的不平等を軽減、結果としてより多くの人が少なくとも損をしない状態になる # 全飴(貯金分も含む)を使った配布total_to_distribute = self.total_contribution # 各グループの貢献比率計算 a_ratio = self.total_a_contribution / self.total_contribution b_ratio = self.total_b_contribution / self.total_contribution c_ratio = self.total_c_contribution / self.total_contribution # 各グループへの配布数決定 a_share = int(total_to_distribute * a_ratio) b_share = int(total_to_distribute * b_ratio) c_share = int(total_to_distribute * c_ratio) # 端数調整 remainder =total_to_distribute - (a_share + b_share + c_share) if remainder> 0: # 端数は最も人数の多いCグループに c_share += remainder # Aグループの配布(均等配分) per_a = a_share // self.group_a_count self.results['A'][per_a] = self.group_a_count # Bグループの配布(均等配分) per_b = b_share // self.group_b_count b_remainder = b_share % self.group_b_count self.results['B'][per_b] = self.group_b_count - b_remainder if per_b + 1> 0 and b_remainder> 0: self.results['B'][per_b + 1] = b_remainder # Cグループの配布(均等配分) per_c = c_share // self.group_c_count c_remainder = c_share % self.group_c_count self.results['C'][per_c] = self.group_c_count - c_remainder if per_c + 1> 0 and c_remainder> 0: self.results['C'][per_c + 1] = c_remainderdef calculate_net_gain(self): """設計意図: この関数は各グループの純利益/損失を計算し、資源分配の公平性を定量的に評価できるようにします。純利益/損失は個人の観点から見た経済的公正性の重要な指標です。 """net_gains = {} # Aグループの純利益計算 a_contribution = self.contribution_per_a a_distribution = list(self.results['A'].keys())[0] # 全員が同じ数を受け取る前提net_gains['A'] = a_distribution - a_contribution # BとCグループの純利益計算(加重平均) forgroup, contribution_per_person in [('B', self.contribution_per_b), ('C', self.contribution_per_c)]:total_gain = 0 for received, count in self.results[group].items():total_gain += (received - contribution_per_person) * countnet_gains[group] =total_gain / (self.group_b_count ifgroup == 'B' else self.group_c_count) returnnet_gainsdef analyze_results(self): """設計意図: この分析関数は、各グループの分配結果を詳細に調査し、制度設計の公平性、貢献度と報酬の関係、およびシステムの持続可能性を評価します。政策分析においては、こうした多角的な検証が重要です。 """ # 各グループの純利益/損失net_gains = self.calculate_net_gain() # 貢献度分析 contribution_percentage = { 'A': (self.total_a_contribution / self.total_contribution) *100, 'B': (self.total_b_contribution / self.total_contribution) *100, 'C': (self.total_c_contribution / self.total_contribution) *100 } # 飴を受け取った人の割合 received_percentage = { 'A': sum(count for received, count in self.results['A'].items() if received> 0) / self.group_a_count *100, 'B': sum(count for received, count in self.results['B'].items() if received> 0) / self.group_b_count *100, 'C': sum(count for received, count in self.results['C'].items() if received> 0) / self.group_c_count *100 } #分析結果の表示print("\n===== 飴の配布システム分析 =====")print(f"総飴数: {self.total_contribution}個 (分配用: {self.distribution_limit}個,貯金: {self.savings}個)")print("\n---グループごとの貢献と結果 ---") forgroup in ['A', 'B', 'C']:group_size =getattr(self, f"group_{group.lower()}_count") contribution_per_person =getattr(self, f"contribution_per_{group.lower()}")total_contribution =getattr(self, f"total_{group.lower()}_contribution")print(f"\n{group}グループ ({group_size}人):")print(f" 貢献: 1人あたり{contribution_per_person}個 (総計: {total_contribution}個, 全体の{contribution_percentage[group]:.1f}%)")print(f" 受け取り状況:") for received, count in sorted(self.results[group].items()):print(f" {received}個: {count}人 ({count/group_size*100:.1f}%)")print(f" 飴を受け取った割合: {received_percentage[group]:.1f}%")print(f"純利益/損失: 1人あたり平均 {net_gains[group]:.2f}個")print("\n--- 全体的な公平性分析 ---")print(f"最も得したグループ: {max(net_gains,key=net_gains.get)}グループ (+{max(net_gains.values()):.2f}個/人)")print(f"最も損したグループ: {min(net_gains,key=net_gains.get)}グループ ({min(net_gains.values()):.2f}個/人)") # 全員に飴が配布されたかどうかall_received =all(sum(count for received, count in self.results[group].items() if received> 0) ==getattr(self, f"group_{group.lower()}_count") forgroup in ['A', 'B', 'C'])print(f"\n前提条件「全員に配布」の充足: {'はい' ifall_received else 'いいえ'}") if notall_received:total_without = sum(self.results['B'][0] + self.results['C'][0])print(f" 飴を受け取れなかった人数: {total_without}人") returnnet_gains, contribution_percentage, received_percentagedef visualize_results(self): """設計意図:データの可視化は政策の効果や不平等性を直感的に理解するために重要です。 このようなグラフィカル表現によって、各グループ間の格差や制度設計の問題点を 一目で理解できるようになります。 """ #グラフのセットアップfig, axes = plt.subplots(2, 2,figsize=(14,10)) # 1. 貢献度のグラフ contributions = [self.total_a_contribution, self.total_b_contribution, self.total_c_contribution] axes[0, 0].bar(['Aグループ', 'Bグループ', 'Cグループ'], contributions) axes[0, 0].set_title('グループごとの総貢献飴数') axes[0, 0].set_ylabel('飴の数') # 貢献度の割合をアノテーションとして追加total = sum(contributions) for i, v in enumerate(contributions): percentage = v /total *100 axes[0, 0].text(i, v +100, f'{percentage:.1f}%', ha='center') # 2. 1人あたりの貢献度と受け取り数の比較group_names = ['Aグループ', 'Bグループ', 'Cグループ'] contribution_per_person = [self.contribution_per_a, self.contribution_per_b, self.contribution_per_c] # 各グループの平均受け取り数を計算 received_per_person = [] forgroup, letter inzip(group_names, ['A', 'B', 'C']):total_received = sum(received * count for received, count in self.results[letter].items())group_size =getattr(self, f"group_{letter.lower()}_count") received_per_person.append(total_received /group_size) x =np.arange(len(group_names)) width = 0.35 axes[0, 1].bar(x - width/2, contribution_per_person, width, label='提出') axes[0, 1].bar(x + width/2, received_per_person, width, label='受け取り') #純利益/損失をアノテーションとして追加 for i in range(len(group_names)):net = received_per_person[i] - contribution_per_person[i]color = 'green' ifnet>= 0 else 'red' axes[0, 1].text(i,max(received_per_person[i], contribution_per_person[i]) + 5, f'{"+" ifnet>= 0 else ""}{net:.1f}', ha='center',color=color) axes[0, 1].set_title('1人あたりの提出・受け取り飴数比較') axes[0, 1].set_xticks(x) axes[0, 1].set_xticklabels(group_names) axes[0, 1].set_ylabel('飴の数') axes[0, 1].legend() # 3. 各グループの受け取り状況の分布 # 各グループの受け取り状況を積み上げ棒グラフで表現group_sizes = [self.group_a_count, self.group_b_count, self.group_c_count] received_counts = [] not_received_counts = [] for letter, size inzip(['A', 'B', 'C'],group_sizes): received = sum(count for received, count in self.results[letter].items() if received> 0) received_counts.append(received) not_received_counts.append(size - received) axes[1, 0].bar(group_names, received_counts, label='飴を受け取った人数') axes[1, 0].bar(group_names, not_received_counts, bottom=received_counts, label='飴を受け取れなかった人数') #割合をアノテーションとして追加 for i in range(len(group_names)): ifgroup_sizes[i]> 0: percentage = received_counts[i] /group_sizes[i] *100 axes[1, 0].text(i, received_counts[i] / 2, f'{percentage:.1f}%', ha='center') axes[1, 0].set_title('グループごとの飴受け取り状況') axes[1, 0].set_ylabel('人数') axes[1, 0].legend() # 4. 貢献度vs報酬の分配公平性 # 貢献度と最終的な飴の配分の比較を円グラフで表現total_contribution = self.total_contribution contribution_shares = [self.total_a_contribution /total_contribution, self.total_b_contribution /total_contribution, self.total_c_contribution /total_contribution] # 実際の配分シェアを計算 distribution_shares = [] for letter in ['A', 'B', 'C']:total_received = sum(received * count for received, count in self.results[letter].items()) distribution_shares.append(total_received / self.distribution_limit) # 2つの円グラフを並べて表示 ax4_1 = axes[1, 1].inset_axes([0, 0, 0.45, 1]) ax4_2 = axes[1, 1].inset_axes([0.55, 0, 0.45, 1]) ax4_1.pie(contribution_shares, labels=group_names, autopct='%1.1f%%') ax4_1.set_title('飴の貢献度割合') ax4_2.pie(distribution_shares, labels=group_names, autopct='%1.1f%%') ax4_2.set_title('飴の配分割合') axes[1, 1].axis('off') plt.tight_layout() plt.show()# 飴の配布システムをシミュレートcandy_system = CandyDistributionSystem()#オリジナルの配布方法を実行print("\n=====オリジナルの配布方法 =====")candy_system.distribute_candies(method='original')original_results = candy_system.analyze_results()candy_system.visualize_results()# 公平な配布方法を実験print("\n\n===== 公平な配布方法のシミュレーション =====")fair_system = CandyDistributionSystem()fair_system.distribute_candies(method='fair')fair_results = fair_system.analyze_results()fair_system.visualize_results()# 公平な配布と元の配布の比較print("\n\n===== 配布方法の比較 =====")print("オリジナル方式と公平方式の純利益/損失差:")net_diff = {}forgroup in ['A', 'B', 'C']:original_net =original_results[0][group] fair_net = fair_results[0][group]diff = fair_net -original_netnet_diff[group] =diffprint(f"{group}グループ: {'+' ifdiff> 0 else ''}{diff:.2f}個/人")print("\n結論:")ifnet_diff['A'] < 0 andnet_diff['B']> 0 andnet_diff['C']> 0:print("公平な再分配により、Aグループの特権が減少し、BとCグループの状況が改善されます。")print("これは構造的不平等の緩和に効果的です。")elifnet_diff['A']> 0:print("興味深いことに、公平な再分配ではAグループさえも利益を得られます。")print("これは、現行システムが特定グループだけでなく全体の非効率性につながっていることを示唆しています。")
CVAT のdocker compose (docker-compose) 後にログイン画面が表示できない問題への対処
django のwebサーバーの起動時ヘルスチェックのデフォルト設定としてストレージの空き容量がストレージの全体容量の10%以上であること というものがある。しかし、2TBストレージを持つ私のメインPCは常時 2%しかストレージの空き容量を確保できない状態であり、CVATをdocker compose 経由で起動することができないという問題がある。
https://phimxitrumvietsub.graphy.com/courses/xemphimsmurfsvietsubfullhd
WEB版のCVAT(10プロジェクトまでは無料)の操作性は遜色ないが、1週間に1度ほどの頻度でWEBサーバーが非常に不安定になる問題が昔からずっと続いており、アノテーション結果のダウンロードや、アノテーション作業の途中経過の保存操作で数時間待たされた挙句、サーバーエラーとなって全ての操作が失敗する事象が頻発するため非常に不安定である。作業効率が著しく悪いため、WEB版のCVATからローカル版のCVATへ意地でも移行したい。
なお、ローカルストレージに10% 以上の空き容量を確保できない人は少ないため、この問題の解決方法を明示的に整理している記事は見つからなかった。
https://phimxitrumvietsub.graphy.com/courses/xemphimxitrumfullhdvietsub
という主張をhttps://togetter.com/li/2568793 で見かけたので、反対意見をここに記しておく。
書いているうちにかなり長くなってしまったが、一個人の感想としてあまり真に受けずに読んでいただけるとよいと思う。
[1]
多く見かけたのは「手描きでしか出せないこだわりがある」といったコメントだが、その多くはAI生成画像を作品として見たことがない人の感想である。
こだわりを持って生成されたAI生成の作品からは、人間がすべて手描きしたものと同等の熱量を受け取ることができる。
ポン出しである程度の雰囲気の画像が生成される、という部分が注目されがちだが、主に構図的な粗がほぼ必ず存在して、非決定的な制御を行うしかない、とても不自由な画材である。
プロンプトを少しずつ変えながら大量に生成して選別することや、目的に沿って生成画像を部分的に修正することなど、この画材を制御する試みの成果が表れている良い作品は、AI生成画像に多く触れていれば通常分かるものである。
したがって、そうした作品を公開している投稿者については個人的には高く評価するし、周囲から高い評価を受けることも妥当であると考えている。
[1a]
付記すべきこととして、そうしたこだわりを持つ主体となれるのは人間だけである、というのは少なくとも現時点では正しい。
現在の画像生成AIは、人間が主体的に環境構築をして、プロンプトを与えて初めて動作する機械的なものであって、無から勝手に生じてきたものではない。
そのような未来においてなおAI生成画像「が」価値を持つのか、という問題は難しい。
[1b]
また厳密にいえば、「手描きであること」自体を価値に含めるような作品は当然ながら画像生成AIでは実現できない。
写真と見分けがつかないように描かれた絵、というものは写真が発明されて200年近く経つ今でも新しく作られているし、子どもが手描きした絵というのは唯一無二の価値があるものである。
手描きの作品の多くがそういった立ち位置に収束しても不思議ではない。
[2]
次に、「AI生成画像は粗製乱造であり平均的に低品質だ」というコメントも見かけたが、手描きの作品も粗製乱造であると考えている。
生成AIが話題になる前から、人々の好みは高度に細分化されており、インターネットに存在する情報のほとんどは特定少数のみに価値があるものである。
個人的な話をするのであれば、まず全年齢対象作品の成人向け二次創作は非常に多く投稿されているが、原作に対する権利侵害であり、少なくとも尊敬がなく受け入れがたいように感じる。
また、一次創作の成人向け作品であっても、わざと汚く描かれた男性が出てくるものは、性的なものに対する真摯さがないという印象になってしまう。
日々たくさんの時間をかけて手描きされている作品も、少なくとも上記のような条件に当てはまる限りは、私にとっては無価値である。
ただし、これらの作品が綺麗に区分けされたインターネット、というものは存在しない。
情報発信が大衆化される価値のほうが明らかに大きく、実際に私は今このほとんど価値がないテキストを匿名の場所にラベルなしで放流する権利を享受している。
AI生成画像について適切な区分けをすべきだという意見も、自分にとって価値がある希少なデータは手間をかけて探すしかない、ということに慣れていないだけなのでは、と考えている。
[2a]
上記の嗜好が生成AI作品を手描きより評価するうえで有利な条件となっていることは認める。
実際、プロンプトに入れないにもかかわらず二次創作が出てきてしまうことはほとんどなく、また安定した構図の絵を出力できるのは1人を指定したときなので、自分で生成した画像については上記2つの心配をせずに済んでいる。
[2b]
AI生成画像であれば一律無価値である、という思想を持つことを否定するわけでは当然ない。
作者のフォローやお気に入り、ユーザーブロック機能による自衛など、既に存在する機能を活用することが優先されるべき、という意図である。
[3]
類似の論点として「低品質でも素人には分からない」というものがあり、現在利用されているものの多くが低品質であることは認めるが、近い将来これも否定されると考えている。
現在の生成AIとくに言語モデルは、教師あり学習ができるデータをほぼ使い切っていて、強化学習によって性能を高めている。
より具体的に言えば、高品質な教師あり学習データを作れなくても、どちらがよいか判定できさえすれば、モデルがそれをもとにより高品質なものを生成できるように学習できる。
少なくとも画像投稿サイトのランキングやSNS上の反応などを見れば、それが十分な品質のアノテーションになっている。
したがって、低品質でもいいという現在の消極的な導入のあとに、人間より高品質だから導入するという選択が広がっていくだろうと予想できる。
[4]
まとめると、[1]こだわりのあるAI生成画像については手描きと同様に過程を評価できることと、[2]個人の評価基準としてはAI生成画像のほうが価値がある可能性が高いことから、私はAI生成画像を好んで鑑賞している。
また、[3]今後の学習でAI生成画像のほうが自然と高品質になり、生成AI「が」いいという時代もすぐ来るのではと考えている。
[4a]
ここまでの議論のとおり、かなり急進的な生成AI推進派を自認しているが、念のため現時点の全体的な立場を表明しておく。
言うまでもないが、現行法上の犯罪に与するような生成AIの開発・利用については明確に反対の立場である。
現状簡単に悪用できてしまうことと、数が多くて追跡できないのは問題なので、免許制にしたり、メタデータとしてAI生成であることが分かるようにするなどの対策はあったほうが望ましい。
一方で、表現の自由を損ねるのでウォーターマークの表示義務はされないべきであると考える。
また、明示的な許諾のない大量のデータで学習することについても、同じ仕組みで得られる翻訳やプログラムなどの利益を享受できなくなることを考えると、規制されるべきではない。
ただし、生成AIの提供によって得られた利益は寡占的な傾向があり、現在の税制で再分配が十分ではなくなる可能性があるので、そのときに対応が必要である。
上記すべては現時点の考えであり今後変わる可能性もあるが、いずれにしても、生成AIの利用について良い塩梅の定説が早めにできてほしいと考えている。
💻
中規模の企業が完全オリジナルのデータのみで学習するのは、コスト面でも技術面でも極めて難しい です。
⸻
1. 莫大なデータ収集コスト
•画像や動画、3Dモデルの大量データを自社でゼロから収集するのはほぼ不可能
•GoogleやOpenAIですらデータ調達に苦労している 現状、中規模企業が同じことをやるのは非現実的
2.品質を保つためのラベリングコスト
• 仮にデータを集められたとしても、機械学習には「正解データ(教師データ)」が必要
• 正確なラベリング(アノテーション)を行うには、専門家チームを長期間雇う必要がある
•企業の規模にもよるが、中規模のソフトウェア企業がこのコストを負担できる可能性は低い
3.既存のAI技術を活用しないメリットがない
• もし本当に「AIを使わず、ディープラーニングに頼らず、高精度なアルゴリズムを作れた」なら、それは業界的な大発見
• なのに論文も特許も出ていない → 本当にそんな技術があるのか疑問
• 結局、「普通にAI技術を使っているけど“(ダーティーな)AI技術ではない”と装っている」可能性が高い
⸻
もし本当に「クリーン」なら証拠を示すべき
大手企業の「クリーン」って言葉の実際の意味:
例えばAdobeFireflyの「クリーン」は完全オリジナルという意味ではない:
•パブリックドメイン素材を利用した
しかもAdobeFireflyは「クリーン」の証拠として下記を提供してる:
•データソース明示
一方、今回のペイントソフトメーカーは「クリーンな学習をしている(かもしれない)」という建前をふわっとさせているだけで、その証拠がない。
⸻
結論:「バレなきゃOK」マーケティングの可能性大
• 「クリーンな学習をしているからAIではない」 という論理は都合のいい言葉遊び
•そもそも本当に「クリーンな学習」なら、証拠を示さないと信用できない
• 中規模企業が独自データのみで学習するのは現実的でないため、実際には何らかの既存AI技術を使っている可能性が高い
•しかし「AI未使用」と言ったほうが、反AIユーザーにも売れるので、マーケティングのためにぼかしている
つまり、
「AIを使っていない」風にとぼかしつつ実は普通に使っている。クリーンでもない。 → でもバレなきゃOKという雑なマーケティングをやっている可能性が高いですね。