feat: 提高标量数量

This commit is contained in:
unanmed 2025-04-30 21:00:45 +08:00
parent 44d6c7410e
commit dc1eb8fa92
41 changed files with 83 additions and 45 deletions

View File

@ -29,22 +29,45 @@ GINKA Model 内部集成了 Minamo Model 用做判别器,与 Ginka Model 对
"yellowGem": { "yellowGem": {
"30": 1 "30": 1
}, },
"item": [47, 49, 50, 51, 52, 53], "item": {
"47": 1,
"49": 1,
"50": 0,
"51": 1,
"52": 1,
"53": 2
},
"potion": { "potion": {
"31": 100, "31": 100,
"32": 200, "32": 200,
"33": 400, "33": 400,
"34": 800 "34": 800
}, },
"key": [21, 22, 23], "key": {
"door": [81, 82, 83, 85], "21": 0,
"wall": [1, 17] "22": 1,
"23": 2,
"24": 2,
"25": 2
},
"door": {
"81": 0,
"82": 1,
"83": 2,
"84": 2,
"85": 3,
"86": 2
},
"wall": [1, 17],
"decoration": [],
"floor": [87, 88],
"arrow": [91, 92, 93, 94]
}, },
"data": {} "data": {}
} }
``` ```
其中,`clip` 属性表示你的每张地图的那一部分会被当成数据集,例如填写 `[0, 0, 13, 13]` 就会让坐标为 `(0, 0)`,长宽为 `(13, 13)` 的矩形内容作为数据集。`special` 不用管。 其中,`clip` 属性表示你的每张地图的那一部分会被当成数据集,例如填写 `[0, 0, 13, 13]` 就会让坐标为 `(0, 0)`,长宽为 `(13, 13)` 的矩形内容作为数据集。`special` 不用管。注意装饰所使用的贴图是白墙,如果白墙是墙壁的话,需要将白墙设置为墙壁。注意不要忘记保存
2. 使用 [在线工具](https://unanmed.github.io/ginka-process) 处理数据,需要给每个地图添加标签,为每个图块分配种类,有一些图块包含多种等级,需要填写正确。 2. 使用 [在线工具](https://unanmed.github.io/ginka-process) 处理数据,需要给每个地图添加标签,为每个图块分配种类,有一些图块包含多种等级,需要填写正确。
3. 将 `project` 文件夹打包发给我 3. 将 `project` 文件夹打包发给我

View File

@ -28,16 +28,16 @@ function convert(
const clipped: number[][] = []; const clipped: number[][] = [];
// 1. 裁剪 // 1. 裁剪
for (let nx = x; nx < x + w; nx++) { for (let ny = y; ny < y + w; ny++) {
const row: number[] = []; const row: number[] = [];
for (let ny = y; ny < y + h; ny++) { for (let nx = y; nx < x + h; nx++) {
row.push(map[ny][nx]); row.push(map[ny][nx]);
} }
clipped.push(row); clipped.push(row);
} }
const res: number[][] = Array.from({ length: clipped.length }, () => const res: number[][] = Array.from({ length: clipped.length }, () =>
Array.from({ length: clipped[0].length }) Array.from({ length: clipped[0].length }, () => 0)
); );
// 2. 初步映射 // 2. 初步映射
@ -278,12 +278,18 @@ function range(from: number, to: number) {
return Array.from({ length }, (_, i) => i + from); return Array.from({ length }, (_, i) => i + from);
} }
export function getGinkaRatio(map: number[][]) { export function getGinkaRatio(map: number[][]): number[] {
return [ const arr: number[] = Array(16).fill(0);
getRatio(map, [1, ...range(3, 32)]), arr[0] = getRatio(map, [1, ...range(3, 32)]);
getRatio(map, [26, 27, 28]), arr[1] = getRatio(map, [1]);
getRatio(map, range(7, 26)), arr[2] = getRatio(map, [2]);
getRatio(map, [3, 4, 5, 6]), arr[3] = getRatio(map, [3, 4, 5, 6]);
getCount(map, [29, 30]) arr[4] = getRatio(map, [26, 27, 28]);
]; arr[5] = getRatio(map, range(7, 26));
arr[6] = getRatio(map, range(10, 19));
arr[7] = getRatio(map, range(19, 23));
arr[8] = getRatio(map, [7, 8, 9]);
arr[9] = getCount(map, [23, 24, 25]);
arr[10] = getCount(map, [29, 30]);
return arr;
} }

View File

@ -13,7 +13,10 @@ class MinamoVisionModel(nn.Module):
spectral_norm(nn.Conv2d(in_ch*2, in_ch*4, 3)), #9*9 spectral_norm(nn.Conv2d(in_ch*2, in_ch*4, 3)), #9*9
nn.LeakyReLU(0.2), nn.LeakyReLU(0.2),
spectral_norm(nn.Conv2d(in_ch*4, out_ch, 3)), # 7*7 spectral_norm(nn.Conv2d(in_ch*4, in_ch*8, 3)), # 7*7
nn.LeakyReLU(0.2),
spectral_norm(nn.Conv2d(in_ch*8, out_ch, 3)), # 5*5
nn.LeakyReLU(0.2), nn.LeakyReLU(0.2),
) )

View File

@ -6,13 +6,12 @@ from torch.utils.data import Dataset
import torch import torch
import torch.nn.functional as F import torch.nn.functional as F
from typing import List from typing import List
from shared.utils import random_smooth_onehot
STAGE1_MASK = [0, 1, 10, 11] STAGE1_MASK = [0, 1, 2, 29, 30]
STAGE1_REMOVE = [2, 3, 4, 5, 6, 7, 8, 9, 12, 13] STAGE1_REMOVE = list(range(3, 29))
STAGE2_MASK = [6, 7, 8, 9] STAGE2_MASK = [3, 4, 5, 6, 26, 27, 28]
STAGE2_REMOVE = [2, 3, 4, 5, 12, 13] STAGE2_REMOVE = list(range(7, 26))
STAGE3_MASK = [2, 3, 4, 5, 12, 13] STAGE3_MASK = list(range(7, 26))
STAGE3_REMOVE = [] STAGE3_REMOVE = []
def load_data(path: str): def load_data(path: str):

View File

@ -9,13 +9,13 @@ from shared.constant import VISION_WEIGHT, TOPO_WEIGHT
from ..critic.model import MinamoModel from ..critic.model import MinamoModel
CLASS_NUM = 32 CLASS_NUM = 32
ILLEGAL_MAX_NUM = 13 ILLEGAL_MAX_NUM = 30
STAGE_ALLOWED = [ STAGE_ALLOWED = [
[], [],
[0, 1, 10, 11], [0, 1, 2, 29, 30],
[6, 7, 8, 9], [3, 4, 5, 6, 26, 27, 28],
[2, 3, 4, 5, 12, 13] list(range(7, 26))
] ]
def get_not_allowed(classes: list[int], include_illegal=False): def get_not_allowed(classes: list[int], include_illegal=False):
@ -30,14 +30,13 @@ def get_not_allowed(classes: list[int], include_illegal=False):
return res return res
def outer_border_constraint_loss(pred: torch.Tensor, allowed_classes=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13]): def outer_border_constraint_loss(pred: torch.Tensor, allowed_classes=[*list(range(0, 29)), 30]):
""" """
强制地图最外圈像素必须为指定类别墙或箭头 强制地图最外圈像素必须为指定类别墙或箭头
参数: 参数:
pred: 模型输出的概率分布形状 [B, C, H, W] pred: 模型输出的概率分布形状 [B, C, H, W]
allowed_classes: 允许出现在外圈的类别列表默认[1,11] allowed_classes: 允许出现在外圈的类别列表
penalty_scale: 惩罚强度系数
返回: 返回:
loss: 标量损失值 loss: 标量损失值
@ -62,12 +61,12 @@ def outer_border_constraint_loss(pred: torch.Tensor, allowed_classes=[0, 1, 2, 3
return loss_unallowed return loss_unallowed
def inner_constraint_loss(pred: torch.Tensor, allowed=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13]): def inner_constraint_loss(pred: torch.Tensor, allowed=list(range(0, 30))):
"""限定内部允许出现的图块种类 """限定内部允许出现的图块种类
Args: Args:
pred (torch.Tensor): 模型输出的概率分布 [B, C, H, W] pred (torch.Tensor): 模型输出的概率分布 [B, C, H, W]
unallowed (list, optional): 在地图中部最外圈允许出现的图块种类. Defaults to [11]. allowed (list, optional): 在地图中部最外圈允许出现的图块种类
""" """
B, C, H, W = pred.shape B, C, H, W = pred.shape
@ -100,7 +99,7 @@ def _create_distance_kernel(size):
def entrance_constraint_loss( def entrance_constraint_loss(
pred: torch.Tensor, pred: torch.Tensor,
entrance_classes=[10, 11], # 假设10是楼梯11是箭头 entrance_classes=[29, 30],
min_distance=9, min_distance=9,
presence_threshold=0.8, presence_threshold=0.8,
lambda_presence=1.0, lambda_presence=1.0,

View File

@ -17,14 +17,22 @@ from shared.image import matrix_to_image_cv
# 标签定义: # 标签定义:
# 0. 蓝海, 1. 红海, 2: 室内, 3. 野外, 4. 左右对称, 5. 上下对称, 6. 伪对称, 7. 咸鱼层, # 0. 蓝海, 1. 红海, 2: 室内, 3. 野外, 4. 左右对称, 5. 上下对称, 6. 伪对称, 7. 咸鱼层,
# 8. 剧情层, 9. 水层, 10. 爽塔, 11. Boss层, 12. 纯Boss层, 13. 多房间, 14. 多走廊, 15. 道具塔 # 8. 剧情层, 9. 水层, 10. 爽塔, 11. Boss层, 12. 纯Boss层, 13. 多房间, 14. 多走廊, 15. 道具风
# 16. 区域入口, 17. 区域连接, 18. 有机关门, 19. 道具层, 20. 斜向对称, 21. 左右通道, 22. 上下通道, 23. 多机关门
# 24. 中心对称, 25. 部分对称, 26. 鱼骨
# 标量值定义: # 标量值定义:
# 0. 整体密度,非空白图块/地图面积,空白图块还包括装饰图块 # 0. 整体密度,非空白图块/地图面积,空白图块还包括装饰图块
# 1. 怪物密度,怪物数量/地图面积 # 1. 墙体密度,墙壁/地图面积
# 2. 资源密度,资源数量/地图面积 # 2. 装饰密度,装饰数量/地图面积
# 3. 门密度,门数量/地图面积 # 3. 门密度,门数量/地图面积
# 4. 入口数量 # 4. 怪物密度,怪物数量/地图面积
# 5. 资源密度,资源数量/地图面积
# 6. 宝石密度,宝石数量/地图面积
# 7. 血瓶密度,血瓶数量/地图面积
# 8. 钥匙密度,钥匙数量/地图面积
# 9. 道具数量
# 10. 入口数量
# 图块定义: # 图块定义:
# 0. 空地, 1. 墙壁, 2. 装饰(用于野外装饰,视为空地), # 0. 空地, 1. 墙壁, 2. 装饰(用于野外装饰,视为空地),

View File

@ -6,10 +6,10 @@ import torch
import torch.nn.functional as F import torch.nn.functional as F
from torch_geometric.loader import DataLoader from torch_geometric.loader import DataLoader
from tqdm import tqdm from tqdm import tqdm
from minamo.model.model import MinamoModel from .critic.model import MinamoModel
from .dataset import GinkaDataset from .dataset import GinkaDataset
from .model.loss import GinkaLoss from .generator.loss import GinkaLoss
from .model.model import GinkaModel from .generator.model import GinkaModel
from shared.image import matrix_to_image_cv from shared.image import matrix_to_image_cv
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

View File

@ -26,15 +26,15 @@ def matrix_to_image_cv(map_matrix, tile_set, tile_size=32):
if '0' in tile_set: if '0' in tile_set:
canvas[y:y+tile_size, x:x+tile_size] = tile_set['0'][:, :, :3] # 仅填充 RGB canvas[y:y+tile_size, x:x+tile_size] = tile_set['0'][:, :, :3] # 仅填充 RGB
if tile_index == '11': if tile_index == '30':
if row == 0: if row == 0:
tile_index = '11_1' tile_index = '30_1'
elif row == W - 1: elif row == W - 1:
tile_index = '11_3' tile_index = '30_3'
elif col == 0: elif col == 0:
tile_index = '11_2' tile_index = '30_2'
elif col == H - 1: elif col == H - 1:
tile_index = '11_4' tile_index = '30_4'
# 叠加其他透明图块 # 叠加其他透明图块
if tile_index in tile_set and tile_index != 0: if tile_index in tile_set and tile_index != 0:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 699 B

After

Width:  |  Height:  |  Size: 406 B

BIN
tiles/11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

After

Width:  |  Height:  |  Size: 396 B

BIN
tiles/14.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

BIN
tiles/15.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

BIN
tiles/16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

BIN
tiles/17.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B

BIN
tiles/18.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

BIN
tiles/19.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 368 B

After

Width:  |  Height:  |  Size: 847 B

BIN
tiles/20.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

BIN
tiles/21.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

BIN
tiles/22.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

BIN
tiles/23.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

BIN
tiles/24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

BIN
tiles/25.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

BIN
tiles/26.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

BIN
tiles/27.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

BIN
tiles/28.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

BIN
tiles/29.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 426 B

View File

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 323 B

View File

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 311 B

View File

Before

Width:  |  Height:  |  Size: 312 B

After

Width:  |  Height:  |  Size: 312 B

View File

Before

Width:  |  Height:  |  Size: 308 B

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 B

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 B

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 B

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 B

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 377 B

BIN
tiles/999.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B