import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
from tqdm import tqdm
# データセットの変換(リサイズと正規化)
transform = transforms.Compose([
transforms.Resize((64, 64)),
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,)) # ピクセル値を[-1, 1]の範囲にスケーリング
])
# AnimeFaceDatasetのロード
dataset = datasets.ImageFolder(root='C:/Users/tyosu/projects/anime_faces',transform=transform)
dataloader = DataLoader(dataset, batch_size=64, shuffle=True)
# Generator(生成モデル)
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.main = nn.Sequential(
nn.Linear(100, 256),
nn.ReLU(True),
nn.Linear(256, 512),
nn.ReLU(True),
nn.Linear(512, 1024),
nn.ReLU(True),
nn.Linear(1024, 64 * 64 * 3),
nn.Tanh()
)
def forward(self, input):
output = self.main(input)
return output.view(-1, 3, 64, 64)
# Discriminator(判別モデル)
class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
self.main = nn.Sequential(
nn.Linear(64 * 64 * 3, 1024),
nn.ReLU(True),
nn.Linear(1024, 512),
nn.ReLU(True),
nn.Linear(512, 256),
nn.ReLU(True),
nn.Linear(256, 1),
nn.Sigmoid()
)
def forward(self, input):
input_flat = input.view(-1, 64 * 64 * 3)
return self.main(input_flat)
# モデルのインスタンス化
G = Generator()
D = Discriminator()
# ロス関数とオプティマイザ
criterion = nn.BCELoss()
optimizerD = optim.Adam(D.parameters(), lr=0.0002)
optimizerG = optim.Adam(G.parameters(), lr=0.0002)
# ランダムノイズ生成関数
def generate_noise(batch_size):
return torch.randn(batch_size, 100)
# トレーニングループ
num_epochs = 50
for epoch in range(num_epochs):
for i, (real_images, _) in enumerate(tqdm(dataloader)):
batch_size = real_images.size(0)
# 本物の画像のラベルは1、偽物の画像のラベルは0
real_labels = torch.ones(batch_size, 1)
fake_labels = torch.zeros(batch_size, 1)
# Discriminatorの学習
optimizerD.zero_grad()
outputs = D(real_images)
real_loss = criterion(outputs, real_labels)
noise = generate_noise(batch_size)
fake_images = G(noise)
outputs = D(fake_images.detach())
fake_loss = criterion(outputs, fake_labels)
d_loss = real_loss + fake_loss
d_loss.backward()
optimizerD.step()
# Generatorの学習
optimizerG.zero_grad()
outputs = D(fake_images)
g_loss = criterion(outputs, real_labels) # 生成画像を本物と認識させたい
g_loss.backward()
optimizerG.step()
print(f'Epoch [{epoch+1}/{num_epochs}] | d_loss: {d_loss.item()} | g_loss: {g_loss.item()}')
# 生成された画像を表示
if (epoch + 1) % 10 == 0:
fake_images = G(generate_noise(64)).detach().cpu()
plt.imshow(fake_images[0].permute(1, 2, 0) * 0.5 + 0.5)
タグ: programming
簡単な画像生成AI python
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
from torchvision.utils import save_image # 画像保存のための関数
import os # ファイルの保存先を指定するためのライブラリ
# VAEのエンコーダーとデコーダー
class VAE(nn.Module):
def __init__(self, input_dim=784, hidden_dim=400, latent_dim=20):
super(VAE, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.fc21 = nn.Linear(hidden_dim, latent_dim)
self.fc22 = nn.Linear(hidden_dim, latent_dim)
self.fc3 = nn.Linear(latent_dim, hidden_dim)
self.fc4 = nn.Linear(hidden_dim, input_dim)
def encode(self, x):
h1 = torch.relu(self.fc1(x))
return self.fc21(h1), self.fc22(h1)
def reparameterize(self, mu, logvar):
std = torch.exp(0.5 * logvar)
eps = torch.randn_like(std)
return mu + eps * std
def decode(self, z):
h3 = torch.relu(self.fc3(z))
return torch.sigmoid(self.fc4(h3))
def forward(self, x):
mu, logvar = self.encode(x.view(-1, 784))
z = self.reparameterize(mu, logvar)
return self.decode(z), mu, logvar
# VAEの損失関数
def loss_function(recon_x, x, mu, logvar):
BCE = nn.functional.binary_cross_entropy(recon_x, x.view(-1, 784), reduction='sum')
KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())
return BCE + KLD
# モデルの定義とデータローダーの準備
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
vae = VAE().to(device)
optimizer = optim.Adam(vae.parameters(), lr=1e-3)
transform = transforms.ToTensor()
train_dataset = datasets.MNIST('.', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=128, shuffle=True)
# トレーニングループ
vae.train()
for epoch in range(10): # 10エポックで学習
train_loss = 0
for batch_idx, (data, _) in enumerate(train_loader):
data = data.to(device)
optimizer.zero_grad()
recon_batch, mu, logvar = vae(data)
loss = loss_function(recon_batch, data, mu, logvar)
loss.backward()
train_loss += loss.item()
optimizer.step()
print(f'Epoch {epoch + 1}, Loss: {train_loss / len(train_loader.dataset)}')
# 学習したモデルで画像生成
vae.eval()
with torch.no_grad():
z = torch.randn(64, 20).to(device)
sample = vae.decode(z).cpu()
sample = sample.view(64, 1, 28, 28) # 28x28の画像サイズに変換 (MNISTデータのフォーマット)
# 保存先ディレクトリを指定
os.makedirs('generated_images', exist_ok=True)
save_image(sample, 'generated_images/sample.png')
print("画像生成完了: 'generated_images/sample.png' に保存されました")
原神VR企画書
プロジェクト名: 「原神VRプロジェクト」
概要:
「原神」を仮想現実(VR)で楽しめるようにすることを目指したプロジェクト。プレイヤーが「原神」の広大な世界を360度の視界で体験し、臨場感のあるバトルや冒険が可能になる新しいプレイスタイルを提供します。本プロジェクトは、既存の「原神」のシステムをベースにしつつ、VRに特化した操作性とインタラクションを追加します。
1. 目的
- プレイヤーに「原神」の世界をより没入的に体験させること。
- VR技術を用いることで、ゲーム内での冒険、戦闘、探索を現実に近い感覚で楽しめる環境を提供。
- 原神ファンやVRユーザー向けに新しいゲームプレイ体験を創出。
2. プロジェクトの目標
- VR対応UIの設計: VRヘッドセットとコントローラーに最適化された直感的なUIを実装。
- 自由視点移動の実現: 360度全方位に視点移動が可能な環境を作り、プレイヤーが自然な視野でゲームを進行できるようにする。
- インタラクティブな戦闘システム: VR特有の操作性を活かしたアクション性を向上させる。
- スケーラブルなグラフィック: VR環境下でも美麗なグラフィックが維持できるよう、軽量化と最適化を行う。
- モーションシステムの調整: プレイヤーがVR内でキャラクターの動きをより自然に操作できるようなモーションシステムを開発。
3. 対象プラットフォーム
- PCVR: 高品質のVR体験を提供するため、Meta Quest 3やValve IndexなどのPCVRヘッドセットを対象とする。
- PS VR2: コンソールユーザー向けにPlayStation VR2対応を検討。
- スタンドアロンVR(将来的なオプション): Quest 3など、スタンドアロン型VR機器にも対応する予定。
4. 主な機能と仕様
4.1 グラフィックとインターフェース
- VR向け最適化: 「原神」のビジュアルをVRの高解像度に対応させるため、シェーダーやテクスチャを最適化。
- 直感的なUI: VRヘッドセットを装着した状態でも使いやすい、手元操作や音声コマンドによるメニュー管理。
- インタラクション強化: キャラクターとの会話や戦闘時のアクションがVRならではのインタラクティブな感覚で楽しめる。
4.2 バトルシステム
- 視点固定/自由切り替え: プレイヤーの好みに応じて、キャラクター視点を固定するか、自由視点で動かすかを選択可能。
- 武器・スキル操作: VRコントローラーを使用して、武器の振り回しやスキル発動を直感的に行えるようにする。
- パーティーメンバー管理: VR環境下で簡単にキャラクターを切り替えられるインターフェースを提供。
4.3 探索・移動
- 自由な視点移動: プレイヤーが360度の視点でフィールドを探索し、世界をよりリアルに感じられるようにする。
- 移動方法の選択: テレポート移動と滑らかな自由移動の2つを提供し、VR酔いを防ぐ対策を実施。
4.4 マルチプレイ対応
- VRマルチプレイの実現: VRでのクロスプレイを可能にし、他のプレイヤーとリアルタイムで冒険ができるようにする。
5. 開発スケジュール
フェーズ1: 企画・設計(3ヶ月)
- プロジェクト計画の策定
- 技術要件の分析
- プロトタイプの開発
フェーズ2: 開発(6ヶ月)
- VR向けUIおよび操作システムの開発
- グラフィックとアニメーションの最適化
- VR戦闘システムの実装
フェーズ3: テスト(3ヶ月)
- 内部テストとバグ修正
- プレイヤーフィードバックの収集
フェーズ4: 公開準備・リリース(2ヶ月)
- マーケティング活動
- 公開前の最終調整とパフォーマンス最適化
6. 開発チーム
- プロジェクトマネージャー: 全体の進捗管理とスケジュール調整。
- UI/UXデザイナー: VR向けのUI/UXデザインを担当。
- ゲームプログラマー: VR対応のプログラムおよび「原神」システムの改良を担当。
- グラフィックデザイナー: VRでの表示に最適化されたビジュアルを制作。
- QAチーム: テストとフィードバック収集を担当。
7. 予算
- 開発費用: 予算の詳細は開発期間に応じて算出。おおよその範囲として$500,000〜$1,000,000を想定。
- VR機材の調達費用: 開発およびテストのためのVRヘッドセットやPCの調達費用を含む。
- マーケティング費用: リリース前のプロモーション活動に必要な費用を計上。
8. 市場調査とターゲットユーザー
- 市場調査: VR市場は急速に拡大しており、特にアクションRPGジャンルにおけるVR需要が高まっていることを確認。Meta Quest 3やPlayStation VR2の新しいユーザー層をターゲットに設定。
- ターゲットユーザー: 原神プレイヤー、VRユーザー、アクションRPGファン、没入型ゲーム体験を求めるゲーマー層を中心にマーケティング。
9. リスク管理
- 技術的リスク: VRに最適化したシステム構築や、ゲーム内でのパフォーマンス維持に対するリスクを慎重に管理。
- ユーザーの適応リスク: VR酔いに対応するための快適な移動手段や、オプション設定の提供。
10. 成功指標
- VR対応版「原神」のリリース後の売上・ダウンロード数。
- プレイヤーからのフィードバックに基づくユーザー満足度。
- VRプラットフォーム上での評判やメディア評価。
以上の計画に基づき、「原神VRプロジェクト」を進めてまいります。
PHP 配列の要素
<?php
$scores = [70, 90, 80];
$scores[] = 60;
$moreScores = [10, 20, 30, ...$scores];
print_r($moreScores);
PHP in_array、array_search
<?php
$names = ["Taro", "Jiro", "Saburo"];
echo array_search("Jiro", $names) .PHP_EOL;
PHP 配列
<?php
$scores = [70, 90, 80];
// echo $scores[0] . PHP_EOL;
// $scores[1] = 95;
// echo $scores[1] . PHP_EOL;
var_dump($scores);
print_r($scores);
ドメイン取得サイト.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Domain Acquisition</title> <style> body { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; height: 100vh; } .container { background-color: #fff; padding: 20px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); border-radius: 8px; text-align: center; width: 100%; max-width: 600px; } h1 { margin-bottom: 20px; } input[type="text"] { width: 80%; padding: 10px; margin: 10px 0; border: 1px solid #ccc; border-radius: 5px; font-size: 16px; } button { padding: 10px 20px; border: none; background-color: #007BFF; color: white; font-size: 16px; border-radius: 5px; cursor: pointer; } button:hover { background-color: #0056b3; } .result { margin-top: 20px; } .loading { display: none; margin-top: 20px; } .domain-list { margin-top: 20px; } .domain-list ul { list-style-type: none; padding: 0; } .domain-list li { background-color: #f9f9f9; margin: 10px 0; padding: 10px; border-radius: 5px; border: 1px solid #ddd; text-align: left; display: flex; justify-content: space-between; } .price { color: green; } .purchase-link { text-decoration: none; background-color: #28a745; color: white; padding: 5px 10px; border-radius: 5px; } .error { color: red; margin-top: 20px; } @media (max-width: 600px) { input[type="text"] { width: 100%; } } </style> </head> <body> <div class="container"> <h1>Check Domain Availability</h1> <form id="domain-form"> <input type="text" id="domain-name" placeholder="Enter domain name" required> <button type="submit">Search</button> </form> <div class="loading" id="loading"> <p>Searching...</p> <img src="https://i.gifer.com/ZZ5H.gif" alt="Loading" width="50"> </div> <div class="result" id="result"></div> <div class="error" id="error"></div> <div class="domain-list" id="domain-list"></div> </div> <script> const form = document.getElementById('domain-form'); const resultDiv = document.getElementById('result'); const loadingDiv = document.getElementById('loading'); const errorDiv = document.getElementById('error'); const domainListDiv = document.getElementById('domain-list'); form.addEventListener('submit', function (event) { event.preventDefault(); const domainName = document.getElementById('domain-name').value.trim(); // フィールドをリセット resultDiv.innerHTML = ''; errorDiv.innerHTML = ''; domainListDiv.innerHTML = ''; loadingDiv.style.display = 'block'; // ローディング表示 if (validateDomainName(domainName)) { // ダミーデータの使用例(実際にはAPIを呼び出します) setTimeout(() => { loadingDiv.style.display = 'none'; // ローディング終了 // 検索結果の仮表示 const available = Math.random() > 0.5; // ランダムに結果を生成 if (available) { resultDiv.innerHTML = `<strong>${domainName}</strong> is available!`; // 他のTLDを提案し、価格と購入リンクを表示 const suggestions = [ { tld: '.com', price: '$10.99', link: 'https://buydomain.com/com' }, { tld: '.net', price: '$9.99', link: 'https://buydomain.com/net' }, { tld: '.org', price: '$11.99', link: 'https://buydomain.com/org' }, { tld: '.info', price: '$8.99', link: 'https://buydomain.com/info' }, { tld: '.co', price: '$12.99', link: 'https://buydomain.com/co' } ]; let domainList = '<ul>'; suggestions.forEach(({ tld, price, link }) => { domainList += `<li>${domainName}${tld} <span class="price">${price}</span> <a href="${link}" target="_blank" class="purchase-link">Buy</a></li>`; }); domainList += '</ul>'; domainListDiv.innerHTML = domainList; } else { resultDiv.innerHTML = `<strong>${domainName}</strong> is already taken.`; } }, 2000); // 実際のAPIではこのタイミングで結果を取得 } else { errorDiv.innerHTML = 'Please enter a valid domain name. It should follow the format: example.com'; loadingDiv.style.display = 'none'; // エラー時はローディングを停止 } }); // ドメイン名のバリデーション関数 function validateDomainName(domain) { const domainPattern = /^[a-zA-Z0-9-]{1,63}\.[a-zA-Z]{2,}$/; return domainPattern.test(domain); } </script> </body> </html>
PHP 無名関数
<?php
// function triple($num)
// {
// return $num * 3;
// }
// $triple = function($num)
// {
// return $num * 3;
// };
$triple = fn($num) => $num * 3;
echo $triple(10) . PHP_EOL;
PHP 関数
<?php
function showAd()
{
echo "---------" . PHP_EOL;
echo "SALE! 50% OFF!" . PHP_EOL;
echo "---------" . PHP_EOL;
}
function showContent()
{
echo "BREAKING NEWS!" . PHP_EOL;
echo "Two baby pandas born at our Zoo!" . PHP_EOL;
}
showAd();
showContent();
showAd();
PHP 実引数
<?php
function printMessage($from, $to)
{
echo "Hi {$to}! from { $from}" . PHP_EOL;
}
printMessage(from: "Taro", to: "Jiro");
printMessage(to: "Shiro", from: "Saburo");