feat: 提高标量数量
33
README.md
@ -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` 文件夹打包发给我
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -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):
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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. 装饰(用于野外装饰,视为空地),
|
||||||
|
|||||||
@ -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")
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
BIN
tiles/10.png
|
Before Width: | Height: | Size: 699 B After Width: | Height: | Size: 406 B |
BIN
tiles/11.png
Normal file
|
After Width: | Height: | Size: 291 B |
BIN
tiles/12.png
|
Before Width: | Height: | Size: 412 B After Width: | Height: | Size: 341 B |
BIN
tiles/13.png
|
Before Width: | Height: | Size: 419 B After Width: | Height: | Size: 396 B |
BIN
tiles/14.png
Normal file
|
After Width: | Height: | Size: 289 B |
BIN
tiles/15.png
Normal file
|
After Width: | Height: | Size: 344 B |
BIN
tiles/16.png
Normal file
|
After Width: | Height: | Size: 419 B |
BIN
tiles/17.png
Normal file
|
After Width: | Height: | Size: 305 B |
BIN
tiles/18.png
Normal file
|
After Width: | Height: | Size: 358 B |
BIN
tiles/19.png
Normal file
|
After Width: | Height: | Size: 441 B |
BIN
tiles/2.png
|
Before Width: | Height: | Size: 368 B After Width: | Height: | Size: 847 B |
BIN
tiles/20.png
Normal file
|
After Width: | Height: | Size: 442 B |
BIN
tiles/21.png
Normal file
|
After Width: | Height: | Size: 448 B |
BIN
tiles/22.png
Normal file
|
After Width: | Height: | Size: 436 B |
BIN
tiles/23.png
Normal file
|
After Width: | Height: | Size: 448 B |
BIN
tiles/24.png
Normal file
|
After Width: | Height: | Size: 643 B |
BIN
tiles/25.png
Normal file
|
After Width: | Height: | Size: 389 B |
BIN
tiles/26.png
Normal file
|
After Width: | Height: | Size: 353 B |
BIN
tiles/27.png
Normal file
|
After Width: | Height: | Size: 382 B |
BIN
tiles/28.png
Normal file
|
After Width: | Height: | Size: 453 B |
BIN
tiles/29.png
Normal file
|
After Width: | Height: | Size: 699 B |
BIN
tiles/3.png
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 426 B |
|
Before Width: | Height: | Size: 323 B After Width: | Height: | Size: 323 B |
|
Before Width: | Height: | Size: 311 B After Width: | Height: | Size: 311 B |
|
Before Width: | Height: | Size: 312 B After Width: | Height: | Size: 312 B |
|
Before Width: | Height: | Size: 308 B After Width: | Height: | Size: 308 B |
BIN
tiles/4.png
|
Before Width: | Height: | Size: 396 B After Width: | Height: | Size: 420 B |
BIN
tiles/5.png
|
Before Width: | Height: | Size: 441 B After Width: | Height: | Size: 422 B |
BIN
tiles/6.png
|
Before Width: | Height: | Size: 426 B After Width: | Height: | Size: 678 B |
BIN
tiles/7.png
|
Before Width: | Height: | Size: 353 B After Width: | Height: | Size: 368 B |
BIN
tiles/8.png
|
Before Width: | Height: | Size: 382 B After Width: | Height: | Size: 365 B |
BIN
tiles/9.png
|
Before Width: | Height: | Size: 453 B After Width: | Height: | Size: 377 B |
BIN
tiles/999.png
Normal file
|
After Width: | Height: | Size: 414 B |