-
↵欢迎大家来我的画进行点评
-
[执行问题] 向大佬请教一个在Mindspore中遇到的问题,ValueError: For 'MatMul', the input dimensions must be equal, but got 'x1_col':import os# os.environ['DEVICE_ID'] = '6'import numpy as npimport mindspore as msfrom mindspore import nnfrom mindspore import contextfrom mindspore import datasetfrom mindspore.train.callback import LossMonitorfrom mindspore.common.api import ms_functionfrom mindspore.ops import operations as Pfrom PIL import Image#当前实验选择算力为Ascend,如果在本地体验,参数device_target设置为"CPU”context.set_context(mode=context.GRAPH_MODE, device_target="Ascend")#要筛选的分辨率条件targetWidth=426targetHeight=640targetChannal=3#读取animal文件夹下所有文件的名字rootDir='animal'fileNameList=['cat','elephant','sheep']label_map = { 'cat': 0, 'elephant': 1, 'sheep': 2}X,Y=[],[]for fileName in fileNameList: fileDir=rootDir+'/'+fileName #print(fileDir) imgNameList=os.listdir(fileDir) #print(imgNameList) for imgName in imgNameList: imgDir=fileDir+'/'+imgName img=Image.open(imgDir) img=np.array(img) if(len(img.shape)==3): width,height,channal=img.shape if width==targetWidth and height==targetHeight and channal==targetChannal:#符合筛选条件的样本留下放到X,其标签放到Y X.append(img.flatten()) Y.append(label_map[fileName])#类别#print(X,Y)#划分训练集和测试集合sampleNum=len(X)train_idx = np.random.choice(sampleNum, int(sampleNum*0.8), replace=False)#取80%的样本作为训练集test_idx = np.array(list(set(range(sampleNum)) - set(train_idx)))#剩下的样本作为测试集X_train=[X[i].astype(np.float32) for i in range(len(X)) if i in train_idx]Y_train=[Y[i] for i in range(len(Y)) if i in train_idx]X_test=[X[i].astype(np.float32) for i in range(len(X)) if i in test_idx]Y_test=[Y[i] for i in range(len(Y)) if i in test_idx]XY_train = list(zip(X_train, Y_train))ds_train = dataset.GeneratorDataset(XY_train, ['x', 'y'])# ds_train.set_dataset_size(sampleNum)ds_train = ds_train.shuffle(buffer_size=sampleNum).batch(32, drop_remainder=True)XY_test = list(zip(X_test, Y_test))ds_test = dataset.GeneratorDataset(XY_test, ['x', 'y'])ds_test = ds_test.batch(30)#具体作用#print(XY_test)for e in X_train: print(e.shape)net = nn.Dense(targetWidth*targetHeight, 3)loss = nn.loss.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')opt = nn.optim.Momentum(net.trainable_params(), learning_rate=0.05, momentum=0.9)model = ms.train.Model(net, loss, opt, metrics={'acc', 'loss'})model.train(25, ds_train, callbacks=[LossMonitor(per_print_times=ds_train.get_dataset_size())], dataset_sink_mode=False)metrics = model.eval(ds_test)print(metrics)本小白正学习如何使用Mindspore,打算用逻辑回归对图片进行分类。输入到回归模型的每个样本数据都是426*640的图片经过flatten后产生的数组,该数组的shape为(817920,),X_train就是若干这样的数组组成的。构建完模型之后,开始训练时产生了如下的错误:[ERROR] ANALYZER(8534,ffffb5cca780,python):2022-11-30-10:59:18.593.719 [mindspore/ccsrc/pipeline/jit/static_analysis/async_eval_result.cc:66] HandleException] Exception happened, check the information as below.The function call stack (See file '/home/ma-user/work/rank_0/om/analyze_fail.dat' for more details):# 0 In file /home/ma-user/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/nn/wrap/cell_wrapper.py(373) loss = self.network(*inputs) ^# 1 In file /home/ma-user/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/nn/wrap/cell_wrapper.py(111) out = self._backbone(data) ^# 2 In file /home/ma-user/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/nn/layer/basic.py(323) if len(x_shape) != 2:# 3 In file /home/ma-user/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/nn/layer/basic.py(326) if self.has_bias:# 4 In file /home/ma-user/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/nn/layer/basic.py(325) x = self.matmul(x, self.weight) ^---------------------------------------------------------------------------ValueError Traceback (most recent call last)/tmp/ipykernel_8534/2891349598.py in 1 model = ms.train.Model(net, loss, opt, metrics={'acc', 'loss'})----> 2 model.train(25, ds_train, callbacks=[LossMonitor(per_print_times=ds_train.get_dataset_size())], dataset_sink_mode=False) 3 metrics = model.eval(ds_test) 4 print(metrics)~/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/train/model.py in train(self, epoch, train_dataset, callbacks, dataset_sink_mode, sink_size) 904 callbacks=callbacks, 905 dataset_sink_mode=dataset_sink_mode,--> 906 sink_size=sink_size) 907 908 def build(self, train_dataset=None, valid_dataset=None, sink_size=-1, epoch=1, jit_config=None):~/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/train/model.py in wrapper(self, *args, **kwargs) 85 raise e 86 else:---> 87 func(self, *args, **kwargs) 88 return wrapper 89 ~/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/train/model.py in _train(self, epoch, train_dataset, callbacks, dataset_sink_mode, sink_size) 540 self._check_reuse_dataset(train_dataset) 541 if not dataset_sink_mode:--> 542 self._train_process(epoch, train_dataset, list_callback, cb_params) 543 elif context.get_context("device_target") == "CPU": 544 logger.info("The CPU cannot support dataset sink mode currently."~/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/train/model.py in _train_process(self, epoch, train_dataset, list_callback, cb_params) 792 cb_params.train_dataset_element = next_element 793 list_callback.step_begin(run_context)--> 794 outputs = self._train_network(*next_element) 795 cb_params.net_outputs = outputs 796 if self._loss_scale_manager and self._loss_scale_manager.get_drop_overflow_update():~/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/nn/cell.py in __call__(self, *args, **kwargs) 584 logger.warning(f"For 'Cell', it's not support hook function in graph mode. If you want to use hook " 585 f"function, please use context.set_context to set pynative mode.")--> 586 out = self.compile_and_run(*args) 587 return out 588 ~/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/nn/cell.py in compile_and_run(self, *inputs) 962 """ 963 self._auto_parallel_compile_and_run = True--> 964 self.compile(*inputs) 965 966 new_inputs = []~/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/nn/cell.py in compile(self, *inputs) 935 """ 936 if self._dynamic_shape_inputs is None or self._dynamic_shape_inputs[0] is None:--> 937 _cell_graph_executor.compile(self, *inputs, phase=self.phase, auto_parallel_mode=self._auto_parallel_mode) 938 else: 939 self._check_compile_dynamic_shape(*inputs)~/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/common/api.py in compile(self, obj, phase, do_convert, auto_parallel_mode, *args) 1004 enable_ge = context.get_context("enable_ge") 1005 self._graph_executor.set_weights_values(obj.parameters_dict())-> 1006 result = self._graph_executor.compile(obj, args_list, phase, self._use_vm_mode()) 1007 obj.compile_cache.add(phase) 1008 if not result:~/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/ops/primitive.py in __check__(self, *args) 465 for track in tracks: 466 fn = getattr(self, 'check_' + track)--> 467 fn(*(x[track] for x in args)) 468 469 ~/anaconda3/envs/MindSpore/lib/python3.7/site-packages/mindspore/ops/operations/math_ops.py in check_shape(self, x1, x2) 1387 if np.all(np.array(x1) != -1) and np.all(np.array(x2) != -1): 1388 if x1_col != x2_row:-> 1389 raise ValueError(f"For '{cls_name}', the input dimensions must be equal, but got 'x1_col': {x1_col} " 1390 f"and 'x2_row': {x2_row}. And 'x' shape {x1}(transpose_a={self.transpose_a}), " 1391 f"'y' shape {x2}(transpose_b={self.transpose_b}).")ValueError: For 'MatMul', the input dimensions must be equal, but got 'x1_col': 817920 and 'x2_row': 272640. And 'x' shape [32, 817920](transpose_a=False), 'y' shape [3, 272640](transpose_b=True).请教各位有经验的大佬,我这个模型或者其他代码有什么问题,如何修改?
-
本文将实现简单的线性回归,演示如何搭建和训练网络待拟合的目标函数为f(x)=5x+3文章分为五部分:生成数据构建拟合模型并初始化参数训练模型训练结果生成数据集在[-10,10]的范围内,生成一系列的随机自变量x并生成对应的因变量y,同时生成一系列的正态分布随机数作为噪声。将噪声加到自变量x对应的因变量y上,得到原始数据。定义数据集生成函数create_data:def create_data(num, w=5.0, b=3.0): for _ in range(num): x = np.random.uniform(-10.0, 10.0) noise = np.random.normal(0, 1) y = x * w + b + noise yield np.array([x]).astype(np.float32), np.array([y]).astype(np.float32)# 用 yield 函数生成可迭代的生成器,当 num 很大时,可很有效的减小内存占用eval_data = list(create_data(50,5,3))#生成50个带噪声的随机点为提高模型泛化能力、提高模型店鲁棒性,我们还会引入增强函数来对原始数据进行数据增强。定义数据集增强函数enhance_data():可以指定数据集的分组大小batch和重复次数。同时用mindspore.dataset.GeneratorDataset将数据集转化为MindSpore所能够识别的数据格式。def enhance_data(num_data, batch_size=16, repeat_size=1): input_data = ds.GeneratorDataset(list(create_data(num_data)), column_names=['data','label']) input_data = input_data.batch(batch_size) input_data = input_data.repeat(repeat_size) return input_data#构建了1600个训练的数据:每个batch的大小为1600,分为100个batch进行训练data_number = 1600batch_number = 16repeat_number = 1data_train = enhance_data(data_number, batch_number, repeat_number)构建拟合模型并初始化参数用mindspore.nn.Dense的方法我们可以构造一个线性拟合的模型:f(x)=wx+bmindspore.nn.Dense的官方文档说明如下定义:(可以在MindSpore查看相关文档说明)class LinearNet(nn.Cell): def __init__(self): super(LinearNet, self).__init__() self.fc = nn.Dense(1, 1, Normal(0.02), Normal(0.02)) def construct(self, x):# 必须要有这个函数,MindSpore 对 construct 接口有一定约束 x = self.fc(x) return xnet = LinearNet()model_params = net.trainable_params()for param in model_params:#查看初始化的参数 print(param, param.asnumpy())训练模型首先定义损失函数(Loss Function)来衡量拟合结果的好坏,在这里我们采取均方误差函数MSE定义好损失函数后我们需要定义一个向前传播的网络,用于执行损失函数的计算,这里采用mindspore定义好的接口mindspore.nn.loss.MSELoss在计算好对应参数的损失函数值后,我们需要更新迭代参数来计算下一组参数的损失值,以判断下一步往哪个方向“前进”来找到最终的最低损失函数值;这一功能将用反向传播网络来实现。参数更新迭代我们这里采用Momentum方法,使用mindspore定义好的接口mindspore.nn.Momentum定义好后,我们可以使用mindspore.Model来进行封装训练定义训练模型:net_loss = nn.loss.MSELoss()opt = nn.Momentum(net.trainable_params(), learning_rate=0.005, momentum=0.9)model = Model(net, net_loss, opt)训练结果最后训练出来的结果:y=4.979354x+3.0504797 和预期y=5x+3比较接近
-
实验目标通过本案例的学习和课后作业的练习:了解DQN算法的基本概念了解如何基于DQN训练一个小游戏了解强化学习训练推理游戏的整体流程你也可以将本案例相关的 ipynb 学习笔记分享到 AI Gallery Notebook 版块获得成长值,分享方法请查看此文档。案例内容介绍《2048》是一款单人在线和移动端游戏,由19岁的意大利人Gabriele Cirulli于2014年3月开发。游戏任务是在一个网格上滑动小方块来进行组合,直到形成一个带有有数字2048的方块。该游戏可以上下左右移动方块。如果两个带有相同数字的方块在移动中碰撞,则它们会合并为一个方块,且所带数字变为两者之和。每次移动时,会有一个值为2或者4的新方块出现,所出现的数字都是2的幂。当值为2048的方块出现时,游戏即胜利,该游戏因此得名。(源自维基百科) DQN是强化学习的经典算法之一,最早由DeepMind于2013年发表的论文“Playing Atari with Deep Reinforcement Learning”中提出,属于value based的model free方法,在多种游戏环境中表现稳定且良好。 在本案例中,我们将展示如何基于simple dqn算法,训练一个2048的小游戏。整体流程:安装基础依赖->创建2048环境->构建DQN算法->训练->推理->可视化效果DQN算法的基本结构Deep Q-learning(DQN)是Q-learing和神经网络的结合,利用经验回放来进行强化学习的训练,结构如下:神经网络部分神经网络用来逼近值函数,一般采用全连接层表达特征输入,采用卷积层表达图像输入。其损失函数表达为γ经验折扣率,γ取0,表示只考虑当下,γ取1,表示只考虑未来。经验回放经验回放是指:模型与环境交互得到的(s,a,r,s')会存入一个replay buffer,然后每次从中随机采样出一批样本进行学习。采用该策略的优点如下:减少样本之间的相关性,以近似符合独立同分布的假设;同时增大样本的利用率。探索策略一般采用贪婪探索策略,即agent以ε的概率进行随机探索,其他时间则采取模型计算得到的动作。DQN的整体结构可以简单的表示为:DQN论文Nature DQN论文Nature DQN在DQN的基础上,采用两个结构一样的网络,一个当前Q网络用来选择动作,更新模型参数,另一个目标Q网络用于计算目标Q值。这样可以减少目标Q值和当前的Q值相关性。2048游戏环境简介2048环境来源于GitHub开源项目,继承于gym基本环境类。玩家可以上下左右移动方块,如果方块数字相同,则合并且所带数字变成两者之和。当值为2048的方块出现时,则获得胜利。结束标志只要出现非法移动,即移动的方向的数字无法合并,则该局结束。相比较于传统的可试验多次更加严格,难度提高。奖励函数奖励值为当前方块和累加最大合成数字最大能合成4096注意事项本案例运行环境为 Pytorch-1.0.0,支持 GPU和CPU 运行,请查看《ModelAtrs JupyterLab 硬件规格使用指南》了解切换硬件规格的方法;如果您是第一次使用 JupyterLab,请查看《ModelAtrs JupyterLab使用指导》了解使用方法;如果您在使用 JupyterLab 过程中碰到报错,请参考《ModelAtrs JupyterLab常见问题解决办法》尝试解决问题。实验步骤1. 程序初始化第1步:安装基础依赖!pip install gym第2步:导入相关的库import sysimport timeimport loggingimport argparseimport itertoolsfrom six import StringIOfrom random import sample, randintimport gymfrom gym import spacesfrom gym.utils import seedingimport numpy as npimport torchimport torch.nn as nnfrom PIL import Image, ImageDraw, ImageFontfrom IPython import displayimport matplotlibimport matplotlib.pyplot as plt2. 训练参数初始化¶本案例设置的 epochs = 3000,可以达到较好的训练效果,GPU下训练耗时约10分钟。CPU下训练较慢,建议调小 epochs 的值,如50,以便快速跑通代码。parser = argparse.ArgumentParser()parser.add_argument("--learning_rate", type=float, default=0.001) # 学习率parser.add_argument("--gamma", type=float, default=0.99) # 经验折扣率parser.add_argument("--epochs", type=int, default=50) # 迭代多少局数parser.add_argument("--buffer_size", type=int, default=10000) # replaybuffer大小parser.add_argument("--batch_size", type=int, default=128) # batchsize大小parser.add_argument("--pre_train_model", type=str, default=None) # 是否加载预训练模型parser.add_argument("--use_nature_dqn", type=bool, default=True) # 是否采用nature dqnparser.add_argument("--target_update_freq", type=int, default=250) # 如果采用nature dqn,target模型更新频率parser.add_argument("--epsilon", type=float, default=0.9) # 探索epsilon取值args, _ = parser.parse_known_args()3. 创建环境2048游戏环境继承于gym.Env,主要几个部分:init函数 定义动作空间、状态空间和游戏基本设置step函数 与环境交互,获取动作并执行,返回状态、奖励、是否结束和补充信息reset函数 一局结束后,重置环境render函数 绘图,可视化环境def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." a, b = itertools.tee(iterable) next(b, None) return zip(a, b)class IllegalMove(Exception): passdef stack(flat, layers=16): """Convert an [4, 4] representation into [4, 4, layers] with one layers for each value.""" # representation is what each layer represents representation = 2 ** (np.arange(layers, dtype=int) + 1) # layered is the flat board repeated layers times layered = np.repeat(flat[:, :, np.newaxis], layers, axis=-1) # Now set the values in the board to 1 or zero depending whether they match representation. # Representation is broadcast across a number of axes layered = np.where(layered == representation, 1, 0) return layeredclass Game2048Env(gym.Env): metadata = {'render.modes': ['ansi', 'human', 'rgb_array']} def __init__(self): # Definitions for game. Board must be square. self.size = 4 self.w = self.size self.h = self.size self.squares = self.size * self.size # Maintain own idea of game score, separate from rewards self.score = 0 # Members for gym implementation self.action_space = spaces.Discrete(4) # Suppose that the maximum tile is as if you have powers of 2 across the board. layers = self.squares self.observation_space = spaces.Box(0, 1, (self.w, self.h, layers), dtype=np.int) self.set_illegal_move_reward(-100) self.set_max_tile(None) # Size of square for rendering self.grid_size = 70 # Initialise seed self.seed() # Reset ready for a game self.reset() def seed(self, seed=None): self.np_random, seed = seeding.np_random(seed) return [seed] def set_illegal_move_reward(self, reward): """Define the reward/penalty for performing an illegal move. Also need to update the reward range for this.""" # Guess that the maximum reward is also 2**squares though you'll probably never get that. # (assume that illegal move reward is the lowest value that can be returned self.illegal_move_reward = reward self.reward_range = (self.illegal_move_reward, float(2 ** self.squares)) def set_max_tile(self, max_tile): """Define the maximum tile that will end the game (e.g. 2048). None means no limit. This does not affect the state returned.""" assert max_tile is None or isinstance(max_tile, int) self.max_tile = max_tile # Implement gym interface def step(self, action): """Perform one step of the game. This involves moving and adding a new tile.""" logging.debug("Action {}".format(action)) score = 0 done = None info = { 'illegal_move': False, } try: score = float(self.move(action)) self.score += score assert score <= 2 ** (self.w * self.h) self.add_tile() done = self.isend() reward = float(score) except IllegalMove: logging.debug("Illegal move") info['illegal_move'] = True done = True reward = self.illegal_move_reward # print("Am I done? {}".format(done)) info['highest'] = self.highest() # Return observation (board state), reward, done and info dict return stack(self.Matrix), reward, done, info def reset(self): self.Matrix = np.zeros((self.h, self.w), np.int) self.score = 0 logging.debug("Adding tiles") self.add_tile() self.add_tile() return stack(self.Matrix) def render(self, mode='human'): if mode == 'rgb_array': black = (0, 0, 0) grey = (200, 200, 200) white = (255, 255, 255) tile_colour_map = { 2: (255, 255, 255), 4: (255, 248, 220), 8: (255, 222, 173), 16: (244, 164, 96), 32: (205, 92, 92), 64: (240, 255, 255), 128: (240, 255, 240), 256: (193, 255, 193), 512: (154, 255, 154), 1024: (84, 139, 84), 2048: (139, 69, 19), 4096: (178, 34, 34), } grid_size = self.grid_size # Render with Pillow pil_board = Image.new("RGB", (grid_size * 4, grid_size * 4)) draw = ImageDraw.Draw(pil_board) draw.rectangle([0, 0, 4 * grid_size, 4 * grid_size], grey) fnt = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', 30) for y in range(4): for x in range(4): o = self.get(y, x) if o: draw.rectangle([x * grid_size, y * grid_size, (x + 1) * grid_size, (y + 1) * grid_size], tile_colour_map[o]) (text_x_size, text_y_size) = draw.textsize(str(o), font=fnt) draw.text((x * grid_size + (grid_size - text_x_size) // 2, y * grid_size + (grid_size - text_y_size) // 2), str(o), font=fnt, fill=black) assert text_x_size < grid_size assert text_y_size < grid_size return np.asarray(pil_board) outfile = StringIO() if mode == 'ansi' else sys.stdout s = 'Score: {}\n'.format(self.score) s += 'Highest: {}\n'.format(self.highest()) npa = np.array(self.Matrix) grid = npa.reshape((self.size, self.size)) s += "{}\n".format(grid) outfile.write(s) return outfile # Implement 2048 game def add_tile(self): """Add a tile, probably a 2 but maybe a 4""" possible_tiles = np.array([2, 4]) tile_probabilities = np.array([0.9, 0.1]) val = self.np_random.choice(possible_tiles, 1, p=tile_probabilities)[0] empties = self.empties() assert empties.shape[0] empty_idx = self.np_random.choice(empties.shape[0]) empty = empties[empty_idx] logging.debug("Adding %s at %s", val, (empty[0], empty[1])) self.set(empty[0], empty[1], val) def get(self, x, y): """Return the value of one square.""" return self.Matrix[x, y] def set(self, x, y, val): """Set the value of one square.""" self.Matrix[x, y] = val def empties(self): """Return a 2d numpy array with the location of empty squares.""" return np.argwhere(self.Matrix == 0) def highest(self): """Report the highest tile on the board.""" return np.max(self.Matrix) def move(self, direction, trial=False): """Perform one move of the game. Shift things to one side then, combine. directions 0, 1, 2, 3 are up, right, down, left. Returns the score that [would have] got.""" if not trial: if direction == 0: logging.debug("Up") elif direction == 1: logging.debug("Right") elif direction == 2: logging.debug("Down") elif direction == 3: logging.debug("Left") changed = False move_score = 0 dir_div_two = int(direction / 2) dir_mod_two = int(direction % 2) shift_direction = dir_mod_two ^ dir_div_two # 0 for towards up left, 1 for towards bottom right # Construct a range for extracting row/column into a list rx = list(range(self.w)) ry = list(range(self.h)) if dir_mod_two == 0: # Up or down, split into columns for y in range(self.h): old = [self.get(x, y) for x in rx] (new, ms) = self.shift(old, shift_direction) move_score += ms if old != new: changed = True if not trial: for x in rx: self.set(x, y, new[x]) else: # Left or right, split into rows for x in range(self.w): old = [self.get(x, y) for y in ry] (new, ms) = self.shift(old, shift_direction) move_score += ms if old != new: changed = True if not trial: for y in ry: self.set(x, y, new[y]) if changed != True: raise IllegalMove return move_score def combine(self, shifted_row): """Combine same tiles when moving to one side. This function always shifts towards the left. Also count the score of combined tiles.""" move_score = 0 combined_row = [0] * self.size skip = False output_index = 0 for p in pairwise(shifted_row): if skip: skip = False continue combined_row[output_index] = p[0] if p[0] == p[1]: combined_row[output_index] += p[1] move_score += p[0] + p[1] # Skip the next thing in the list. skip = True output_index += 1 if shifted_row and not skip: combined_row[output_index] = shifted_row[-1] return (combined_row, move_score) def shift(self, row, direction): """Shift one row left (direction == 0) or right (direction == 1), combining if required.""" length = len(row) assert length == self.size assert direction == 0 or direction == 1 # Shift all non-zero digits up shifted_row = [i for i in row if i != 0] # Reverse list to handle shifting to the right if direction: shifted_row.reverse() (combined_row, move_score) = self.combine(shifted_row) # Reverse list to handle shifting to the right if direction: combined_row.reverse() assert len(combined_row) == self.size return (combined_row, move_score) def isend(self): """Has the game ended. Game ends if there is a tile equal to the limit or there are no legal moves. If there are empty spaces then there must be legal moves.""" if self.max_tile is not None and self.highest() == self.max_tile: return True for direction in range(4): try: self.move(direction, trial=True) # Not the end if we can do any move return False except IllegalMove: pass return True def get_board(self): """Retrieve the whole board, useful for testing.""" return self.Matrix def set_board(self, new_board): """Retrieve the whole board, useful for testing.""" self.Matrix = new_board4. 定义DQN算法DQN算法分了两部分构造,拟合函数部分-神经网络算法逻辑本身Replay Buffer部分神经网络结构包含三层卷积网络和一层全连接网络,输出维度为动作空间维度。 神经网络部分可自由设计,以训练出更好的效果。class Net(nn.Module): #obs是状态空间输入,available_actions_count为动作输出维度 def __init__(self, obs, available_actions_count): super(Net, self).__init__() self.conv1 = nn.Conv2d(obs, 128, kernel_size=2, stride=1) self.conv2 = nn.Conv2d(128, 64, kernel_size=2, stride=1) self.conv3 = nn.Conv2d(64, 16, kernel_size=2, stride=1) self.fc1 = nn.Linear(16, available_actions_count) self.relu = nn.ReLU(inplace=True) def forward(self, x): x = x.permute(0, 3, 1, 2) x = self.relu(self.conv1(x)) x = self.relu(self.conv2(x)) x = self.relu(self.conv3(x)) x = self.fc1(x.view(x.shape[0], -1)) return xDQN核心逻辑部分class DQN: def __init__(self, args, obs_dim, action_dim): # 是否加载预训练模型 if args.pre_train_model: print("Loading model from: ", args.pre_train_model) self.behaviour_model = torch.load(args.pre_train_model).to(device) # 如果采用Nature DQN,则需要额外定义target_network self.target_model = torch.load(args.pre_train_model).to(device) else: self.behaviour_model = Net(obs_dim, action_dim).to(device) self.target_model = Net(obs_dim, action_dim).to(device) self.optimizer = torch.optim.Adam(self.behaviour_model.parameters(), args.learning_rate) self.criterion = nn.MSELoss() # 动作维度 self.action_dim = action_dim # 统计学习步数 self.learn_step_counter = 0 self.args = args def learn(self, buffer): # 当replaybuffer中存储的数据大于batchsize时,从中随机采样一个batch的数据学习 if buffer.size >= self.args.batch_size: # 更新target_model的参数 if self.learn_step_counter % args.target_update_freq == 0: self.target_model.load_state_dict(self.behaviour_model.state_dict()) self.learn_step_counter += 1 # 从replaybuffer中随机采样一个五元组(当前观测值,动作,下一个观测值,是否一局结束,奖励值) s1, a, s2, done, r = buffer.get_sample(self.args.batch_size) s1 = torch.FloatTensor(s1).to(device) s2 = torch.FloatTensor(s2).to(device) r = torch.FloatTensor(r).to(device) a = torch.LongTensor(a).to(device) if args.use_nature_dqn: q = self.target_model(s2).detach() else: q = self.behaviour_model(s2) # 每个动作的q值=r+gamma*(1-0或1)*q_max target_q = r + torch.FloatTensor(args.gamma * (1 - done)).to(device) * q.max(1)[0] target_q = target_q.view(args.batch_size, 1) eval_q = self.behaviour_model(s1).gather(1, torch.reshape(a, shape=(a.size()[0], -1))) # 计算损失函数 loss = self.criterion(eval_q, target_q) self.optimizer.zero_grad() loss.backward() self.optimizer.step() def get_action(self, state, explore=True): # 判断是否探索,如果探索,则采用贪婪探索策略决定行为 if explore: if np.random.uniform() >= args.epsilon: action = randint(0, self.action_dim - 1) else: # Choose the best action according to the network. q = self.behaviour_model(torch.FloatTensor(state).to(device)) m, index = torch.max(q, 1) action = index.data.cpu().numpy()[0] else: q = self.behaviour_model(torch.FloatTensor(state).to(device)) m, index = torch.max(q, 1) action = index.data.cpu().numpy()[0] return actionreplay buffer数据存储部分class ReplayBuffer: def __init__(self, buffer_size, obs_space): self.s1 = np.zeros(obs_space, dtype=np.float32) self.s2 = np.zeros(obs_space, dtype=np.float32) self.a = np.zeros(buffer_size, dtype=np.int32) self.r = np.zeros(buffer_size, dtype=np.float32) self.done = np.zeros(buffer_size, dtype=np.float32) # replaybuffer大小 self.buffer_size = buffer_size self.size = 0 self.pos = 0 # 不断将数据存储入buffer def add_transition(self, s1, action, s2, done, reward): self.s1[self.pos] = s1 self.a[self.pos] = action if not done: self.s2[self.pos] = s2 self.done[self.pos] = done self.r[self.pos] = reward self.pos = (self.pos + 1) % self.buffer_size self.size = min(self.size + 1, self.buffer_size) # 随机采样一个batchsize def get_sample(self, sample_size): i = sample(range(0, self.size), sample_size) return self.s1[i], self.a[i], self.s2[i], self.done[i], self.r[i]5. 训练模型初始化环境和算法# 初始化环境env = Game2048Env()device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 初始化dqndqn = DQN(args, obs_dim=env.observation_space.shape[2], action_dim=env.action_space.n)# 初始化replay buffermemory = ReplayBuffer(buffer_size=args.buffer_size, obs_space=(args.buffer_size, env.observation_space.shape[0], env.observation_space.shape[1], env.observation_space.shape[2]))开始训练print('\ntraining...')begin_t = time.time()max_reward = 0for i_episode in range(args.epochs): # 每局开始,重置环境 s = env.reset() # 累计奖励值 ep_r = 0 while True: # 计算动作 a = dqn.get_action(np.expand_dims(s, axis=0)) # 执行动作 s_, r, done, info = env.step(a) # 存储信息 memory.add_transition(s, a, s_, done, r) ep_r += r # 学习优化过程 dqn.learn(memory) if done: print('Ep: ', i_episode, '| Ep_r: ', round(ep_r, 2)) if ep_r > max_reward: max_reward = ep_r print("current_max_reward {}".format(max_reward)) # 保存模型 torch.save(dqn.behaviour_model, "2048.pt") break s = s_print("finish! time cost is {}s".format(time.time() - begin_t))6. 使用模型推理游戏¶#加载模型model = torch.load("2048.pt").to(device)model.eval()s = env.reset()img = plt.imshow(env.render(mode='rgb_array'))while True: plt.axis("off") img.set_data(env.render(mode='rgb_array')) display.display(plt.gcf()) display.clear_output(wait=True) s = torch.FloatTensor(np.expand_dims(s, axis=0)).to(device) a = torch.argmax(model(s), dim=1).cpu().numpy()[0] # take action s_, r, done, info = env.step(a) time.sleep(0.1) if done: break s = s_env.close()plt.close()7. 作业请你调整步骤2中的训练参数,重新训练一个模型,使它在游戏中获得更好的表现。
-
如图我想把numpy创建的变量转换成Tensor但是报错如图
-
[其他问题] RuntimeError: For 'Conv2D', 'C_in' of input 'x' shape divide by parameter 'group' must be equal to 'C_in' of input 'weig运行报错:RuntimeError: For 'Conv2D', 'C_in' of input 'x' shape divide by parameter 'group' must be equal to 'C_in' of input 'weight' shape: 3, but got 'C_in' of input 'x' shape: 224, and 'group': 1.使用的卷积层:输入的图片shape为:对应的输入维度就是3,为什么还是报错是224呢?
-
PCA(主成分分析)PCA(Principal Component Analysis,主成分分析)是一种常用的数据分析方法。PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维。PCA已在人脸识别和图像压缩等领域得到了广泛应用。PCA相关的数学概念•标准差公式为为标准差 在概率统计中最常使用作为统计分布程度上的测量。标准差定义是总体各单位标准值与其平均数离差平方的算术平均数的平方根。它反映组内个体间的离散程度。•标准差在Matlab中的计算如下:•定义一个3*3的矩阵如下•std(a)求矩阵标准差,std(a,0,1)求矩阵列的标准差。Std(a,0,2)求矩阵行的标准差,如果是求整个矩阵的标准差使用std2(a)函数•方差公式为方差是在概率论和统计方差衡量随机变量或一组数据时离散程度的度量。•方差在Matlab中的使用方法如下•V=var(X,flag,dim)•参数解释如下:•X为矩阵或者向量;•flag为权值,当flag等于0时:前置因子是1/(n-1),当flag等于0时:前置因子是1/(n),默认是0;•dim为维数,当dim=1时,表示计算列,当dim=2时,表示计算行,下图为计算行和列的方差的结果。•Matlab中没有直接计算矩阵方差的函数,可以先求得标准差再平方得到•协方差计算公式为协方差在概率论和统计学中用于衡量两个变量的总体误差。而方差是协方差的一种特殊情况,即当两个变量是相同的情况。•协方差矩阵:在统计学与概率论中,协方差矩阵的每个元素是各个向量元素之间的协方差,是从标量随机变量到高维度随机向量的自然推广。•举个例子,我们将为一个假想的三维数据集建立协方差矩阵,实用3个维度,协方差矩阵将有3行3列如下所示:先初始化两个矩阵a,b•其中,对角线的值是两个向量的方差,斜对角线的是两个向量之间的协方差PCA算法的步骤•设有m条n维数据。•1)将原始数据按列组成n行m列矩阵X•2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值•3)求出协方差矩阵•4)求出协方差矩阵的特征值及对应的特征向量•5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P•6)Y=PX即为降维到k维后的数据•使用PCA的方法将二维数组降到一维•初始化矩阵a,如下图•数组a的每行都已经是零均值,求协方差矩阵如下•再求其特征值和特征向量,如下图即特征值为特征向量为我们所求的P矩阵为•最后我们用P的第一行乘以数据矩阵,就得到了降维后的表示:Y即为最终结果人脸识别的实现•1. 准备一个训练集的人脸图像。本实验选取剑桥大学ORL人脸数据库。一共40个不同的人,每人10张人脸图像,随机选取7张用作训练(取平均后作为一张脸),图像分辨率为112*92.•2. 将原始图像的每一行的像素串联在一起,产生一个具有112*92个元素的列向量,每个图像被视为一个向量。然后,使所有的训练集的图像(一共40张)存储在一个单一的矩阵T中,矩阵的每一列是一个图像。•3. 减去均值向量. 均值向量a要首先计算,并且T中的每一个图像都要减掉均值向量。•4. 计算协方差矩阵S的特征值和特征向量。每一个特征向量的维数与原始图像的一致,因此可以被看作是一个图像。因此这些向量被称作特征脸。•5. 选择主成分。一般选择最大的k个特征值,保留对应的特征向量。6. 对每个训练图像的向量,投影到特征空间后得到一组坐标。对测试图像,也作同样的投影运算,得到坐标,与训练图像的坐标进行二范数最小匹配原始图像灰度图像在计算机中的存储形式为a*b*3的矩阵特征脸及生成特征脸的主要代码得到结果(横坐标为特征维数,纵坐标为准确率)匿名用户 发表于2022-10-23 19:48:33 2022-10-23 19:48:33 最后回复 匿名用户 2022-10-23 19:48:3353 0
-
历经三年时间,我们在2022年完成了图灵奖获得者、加州大学洛杉矶分校计算机科学教授,美国国家科学院院士,被誉为“贝叶斯网络之父”的朱迪亚·珀尔大作《因果论:模型、推理和推断》。 这本书原版的第1版写于2000年,开创了因果分析和推断的新思想和新方法,一出版就得到广泛的好评,促进了数据科学、人工智能、机器学习、因果分析等领域新的革命,在学术界产生了很大的影响。 后来又于2009年修订出了第2版,内容上结合当时因果研究的新发展,做了较大的改动。目前我们翻译的这本书英文原版是在2009年出版的,到目前已经有十多年了。 该书中文版的出版有利于广大中国学者、学生和各领域的实践人员了解和掌握因果模型、推理和推断相关的内容。特别是在当前统计学和机器学习流行的时代,如何实现从“数据拟合”到“数据理解”的转变?如何在下一个十年里,从“所有知识都来自数据本身”这一目前占据主流的假设到一个全新的机器学习范式?是否会引发“第二次人工智能革命”? 正如图灵奖授予珀尔时评价他的工作为“人工智能领域的基础性贡献,他提出概率和因果性推理演算法,彻底改变了人工智能最初基于规则和逻辑的方向。” 我们期待这种范式能够为机器学习带来新的技术方向和前进动力,并且最终能够在实际应用中发挥作用。 正如珀尔所说“数据拟合目前牢牢地统治着当前的统计学和机器学习领域,是当今大多数机器学习研究者的主要研究范式,尤其是那些从事连接主义、深度学习和神经网络技术的研究者。” 这种以“数据拟合”为核心的范式在计算机视觉、语音识别和自动驾驶等应用领域取得了令人瞩目的成功。但是,许多数据科学领域的研究人员也已经意识到,从当前实践效果来看,机器学习无法产生智能决策所需的那种理解能力。这些问题包括:稳健性、可迁移性、可解释性等。下面我们来看看例子。 数据统计靠谱吗? 近年来自媒体上的很多人都会觉得自己是统计学家。因为“数据拟合”“所有知识都来自数据本身”为许多重大决策提供了数据统计依据。但是,在进行分析时,我们需要谨慎分析。毕竟,事情可能并不总是乍看之下!一个与我们生活息息相关的案例。10年前,某城市市中心的房价是8000元/平米,共销售了1000万平;高新区是4000元/平米,共销售了100万平;整体来看,该市的平均房价为7636元/平米。现在,市中心10000元/平米,但由于市中心的土地供应少了,只销售了200万平;高新区是6000元/平米,但由于新开发的土地变多了,销售了2000万平;整体来看,现在该市的平均房价为6363元/平米。因此,分区来看房价分别都涨了,但从整体上看,会有产生疑惑:为什么现在的房价反而跌了呢? 图1 房价趋势按照不同区域划分后与总体结论相悖 我们知道这种现象叫作辛普森悖论。这些案例清楚地表明当我们没有给予足够的观察变量时,我们是如何从统计数据中得到了完全错误的模型和结论。就这次新冠大流行而言,我们通常会获得全国范围的统计数据。如果我们按地区或市县进行分组,我们可能会得出截然不同的结论。在全国范围内,我们可以观察到新冠病例数量在下降,尽管某些地区的病例数量会有所增加(这可能预示着下一波浪潮的开始)。如果存在差异很大的群体,例如人口差异很大的地区,则也可能会发生这种情况。在国家数据中,人口密度较低地区的病例激增可能与人口稠密地区的病例下降相形见绌。 类似的基于“数据拟合”的统计问题比比皆是。比如下面两个有趣的例子。 如果我们每年收集尼古拉斯·凯奇每年出演的电影数量和美国溺死人数的数据,我们会发现这两个变量高度相关,数据拟合程度奇高。 图2 尼古拉斯·凯奇每年出演的电影数与美国溺死的人数 如果我们收集每个国家人均牛奶销售量和获得诺贝尔奖人数的数据,我们会发现这两个变量高度相关。 图3 人均牛奶消费量与诺贝尔奖人数 从我们人类的常识认知来说,这些都是伪相关,甚至是悖论。但从数学和概率论的角度来看,表现出伪相关或者悖论的案例无论从数据上还是计算上都是没有问题的。如果有一些因果基础的人都知道,发生这种情况是因为数据中隐藏着所谓的潜伏变量,即未被观察到的混杂因子。 图4 独立变量导致了两个变量之间伪相关 珀尔在《因果论》中给出了解决的范式,详细分析和推导了以上问题,强调了因果与统计之间有着本质的区别,虽然因果分析与推断仍然是建立在统计学的语境上。珀尔提出了干预操作(算子)的基本计算模式,包括后门原则和具体的计算公式,这是当前对于因果关系最为数学化的描述。“因果以及相关的概念(例如随机化、混杂、干预等)不是统计概念”,这是贯穿珀尔因果分析思想的一条基本原理,珀尔称之为第一原理[2]。 那么,目前基于数据驱动的机器学习方法,特别是那些严重依赖于统计学方法的算法,学习到的模型极大可能也会出现半真半假、误导性或者反转性的结果。这是因为这些模型往往是基于观察数据的分布情况进行学习,而非数据生成的机制。 机器学习亟需解决的三个问题 稳健性:随着深度学习方法的流行,计算机视觉、自然语言处理和语音识别等研究大量利用了最先进的深层神经网络结构。但仍然长期存在这样一个事实问题,即在现实世界中,我们采集到数据的分布通常很少是完整的,与实际世界中的分布可能不一致。在计算机视觉应用中,训练集与测试集数据分布可能受到来自诸如像素差、压缩质量,或来自于摄像机位移、旋转或角度等的影响。这些变量其实就是因果概念中的“干预”问题。由此,人们提出了简单的算法来模拟干预,以专门测试分类和识别模型的泛化能力,如空间偏移、模糊、亮度或对比度的变化、背景控制和旋转,以及在多种环境中采集的图像等。到目前为止,尽管我们利用数据增强、预训练、自监督学习等方法在稳健性上取得了一定的进展,但对于如何解决这些问题还没有明确的共识。有人认为这些修正可能是不够的,在独立同分布假设之外进行泛化不仅需要学习变量之间的统计关联,还需要学习潜在的因果模型,以明确数据生成的机制,并允许通过干预概念模拟分布变化。 可迁移性:婴儿对物体的理解基于跟踪随时间变化表现一致的物体,这样的方法可以让婴儿快速学习新的任务,因为他们对物体的知识和直观理解可以重复使用。类似地,能够高效地解决现实世界中的任务需要在新的场景中重用学习到的知识技能。研究已经证明,学习了环境知识的机器学习系统效率更高,通用性更好。如果我们将现实世界模型化,许多模块在不同的任务和环境中表现出相似的行为。因此,面对新环境或新任务,人类或者机器可能只需要调整其内部表示中的几个模块。当学习因果模型时,由于大多数知识(即模块)可以在无须进一步训练的情况下重复使用,从而只需要较少的样本以适应新环境或新任务。 可解释性:可解释性是一个微妙的概念,不能仅仅使用布尔逻辑或统计概率的语言完全描述,它需要额外的干预概念,甚至是反事实的概念。因果关系中的可操纵性定义关注的是这样一个事实,即条件概率(“看到人们打开雨伞表明正在下雨”)无法可靠地预测主动干预的结果(“收起雨伞并不能阻止下雨”)。因果关系被视为推理链的组成部分,它可以为与观察到的分布相去甚远的情况提供预测,甚至可以为纯粹假设的场景提供结论。从这个意义上说,发现因果关系意味着获得可靠的知识,这些知识不受观察到的数据分布和训练任务的限制,从而为可解释的学习提供明确的说明。 因果学习建模的三个层次 具体地说,基于统计模型的机器学习模型只能对相关关系进行建模,而相关关系往往会随着数据分布的变化而变化;而因果模型基于因果关系建模,则抓住了数据生成的本质,反映了数据生成机制的关系,这样的关系更加稳健,具有分布外泛化的能力。比如,在决策理论中,因果关系和统计之间的区别更加清楚。决策理论中有两类问题,一类是已知当前环境,拟采取干预,预测结果。另一类是已知当前环境和结果,反推原因。前者称为求果问题,后者称为溯因问题[3]。 在独立同分布条件下的预测能力 统计模型只是对观察到的现实世界的粗浅描述,因为它们只关注相关关系。对于样本和标签,我们可以通过估计来回答这样的问题:“这张特定的照片中有一只狗的概率是多少?”“已知一些症状,心力衰竭的概率是多少?”。这样的问题是可以通过观察足够多的由所生成的独立同分布数据来回答的。尽管机器学习算法可以把这些事做得很好,但是准确的预测结果对于我们的决策是不够,而因果学习为其提供了一种有益的补充。就前面的例子来说,尼古拉斯·凯奇出演电影的频率和美国溺亡率正相关,我们的确可以训练一个统计学习模型通过尼古拉斯·凯奇出演电影的频率来预测美国溺亡率,但显然这两者并没有什么直接的因果关系。统计模型只有在独立同分布的情况下才是准确的,如果我们做任何的干预来改变数据分布,就会导致统计学习模型出错。 在分布偏移/干预下的预测能力 我们进一步讨论干预问题,它更具挑战性,因为干预(操作)会使我们跳出统计学习中独立同分布的假设。继续用尼古拉斯·凯奇的例子,“今年增加邀请尼古拉斯·凯奇出演电影的数量会增加美国的溺亡率吗?”就是一个干预问题。显然,人为的干预会使得数据分布发生变化,统计学习赖以生存的条件就会被打破,所以它会失效。另一方面,如果我们可以在存在干预的情况下学习一个预测模型,那么这有可能让我们得到一个在现实环境中对分布变化更加稳健的模型。实际上,这里所谓的干预并不是什么新鲜事,很多事情本身就是随时间变化的,例如人的兴趣偏好,或者模型的训练集与测试集本身在分布上就存在不匹配的现象。我们前面已经提到,神经网络的稳健性已经获得了越来越多的关注,成为一个与因果推断紧密连接的研究话题。在分布偏移的情况下预测不能只局限于在测试集上取得高准确率,如果我们希望在实际应用中使用机器学习算法,那么我们必须相信在环境条件改变的情况下,模型的预测结果也是准确的。实际应用中的分布偏移类别可能多种多样,一个模型仅仅在某些测试集上取得好效果,不能代表我们可以在任何情况下都能够信任这个模型,这些测试集可能只是恰好符合这些测试集样本的分布。为了让我们可以在尽可能多的情况下信任预测模型,就必须采用具有回答干预问题能力的模型,至少仅仅使用统计学习模型是不行的。 回答反事实问题的能力 反事实问题涉及推理事情为什么会发生,想象实施不同行为所带来的后果,并由此可以决定采取何种行为来达到期望的结果。回答反事实问题比干预更加困难,但也是对于AI非常关键的挑战。如果一个干预问题是“如果我们现在让一个病人有规律地进行锻炼,那么他心力衰竭的概率会如何变化?”,对应的反事实问题就是“如果这个已经发生心力衰竭的病人一年前就开始锻炼,那他还会得心力衰竭吗?”显然回答这样的反事实问题对于强化学习是很重要的,它们可以通过反思自己的决策,制定反事实假说,再通过实践验证,就像我们的科学研究一样。 因果学习应用 最后,我们来看看如何在各个领域上应用因果学习。2021年诺贝尔经济学奖授予了约书亚·安格里斯特(Joshua D.Angrist)和吉多·因本斯(Guido W.Imbens),表彰“他们对因果关系分析的方法论”贡献。他们研究了因果推断在实证劳动经济学中的应用。诺贝尔经济学奖评选委员认为“自然实验(随机试验或者对照试验)有助于回答重要问题”,但如何“使用观测数据回答因果关系”更具有挑战性。经济学中的重要问题是因果关系问题。如移民如何影响当地人的劳动力市场前景?读研究生能够影响收入增加吗?最低工资对技术工人的就业前景有何影响?这些问题很难回答,因为我们缺乏正确的反事实解释方法。 自从20世纪70年代以来,统计学家就发明了一套计算“反事实”的框架,以揭示两个变量之间的因果效应。经济学家又在此基础上进一步发展了断点回归、双重差分、倾向得分等方法,并且大量地应用在各种经济政策问题的因果性研究上。从6世纪的宗教文本到2021年的因果机器学习,包括因果自然语言处理,我们可以使用机器学习、统计学和计量经济学来模拟因果效应。经济和其他社会科学的分析主要围绕因果效应的估计,即一个特征变量对于结果变量的干预效应。实际上,在大多数情况下,我们感兴趣的事情是所谓的干预效应。干预效应是指干预或者治疗对结果变量的因果影响。比如在经济学中,分析最多的干预效应之一是对企业进行补贴对企业收入的因果影响。为此,鲁宾(Rubin)提出了潜在结果框架(potential outcome framework)。 尽管经济学家和其他社会科学家对因果效应的精确估计能力强于预测能力,但他们对机器学习方法的预测优势也十分感兴趣。例如,精确的样本预测能力或处理大量特征的能力。但正如我们所见到的,经典机器学习模型并非旨在估计因果效应,使用机器学习中现成的预测方法会导致对因果效应的估计存在偏差。那么,我们必须改进现有的机器学习技术,以利用机器学习的优势来持续有效地估计因果效应,这就促使了因果机器学习的诞生! 目前,根据要估计的因果效应类型,因果机器学习可以大致分为两个研究方向。一个重要的方向是改进机器学习方法以用于无偏且一致的平均干预效应估计。该研究领域的模型试图回答以下问题:客户对营销活动的平均反应是什么?价格变化对销售额的平均影响是多少?此外,因果机器学习研究的另一条发展路线是侧重于改进机器学习方法以揭示干预效应的特异性,即识别具有大于或小于平均干预效应的个体亚群。这类模型旨在回答以下问题:哪些客户对营销活动的反应最大?价格变化对销售额的影响如何随着顾客年龄的变化而变化? 除了这些活生生的例子,我们还可以感觉到因果机器学习引起数据科学家兴趣的一个更深刻的原因是模型的泛化能力。具备描述数据之间因果关系的机器学习模型可泛化到新的环境中,但这仍然是目前机器学习的最大挑战之一。 珀尔更深层次地分析这些问题,认为如果机器不会因果推理,我们将永远无法获得达到真正人类水平的人工智能,因为因果关系是我们人类处理和理解周围复杂世界的关键机制。珀尔在《因果论》中文版的序中写到“在下一个十年里,这个框架将与现有的机器学习系统相结合,从而可能引发‘第二次因果革命’。我希望这本书也能使中国读者积极参与到这一场即将到来的革命之中。” 参考文献: [1] 珀尔. 因果论:模型、推理和推断(原书第2版)[M]. 刘礼,等译. 北京:机械工业出版社,2022. [2] 刘礼,吴飞,李廉. 因果关系学习的思维取向和概念分析[J]. 中国大学教学,2021(10):35-42. [3] WANG A G, LIU L, YANG J Y, LI L, Causality Fields in Nonlinear Causal Effect Analysis [J]. Frontiers of Information Technology & Electronic Engineering, 2022,23(8):1277-1286. 推荐阅读: 《因果论:模型、推理和推断(原书第2版)》 作者:[美] 朱迪亚·珀尔(Judea Pearl) 译者:刘礼 杨矫云 廖军 李廉 图灵奖获得者、贝叶斯网络奠基人、美国国家科学院院士、结构因果图的创始人朱迪亚·珀尔因果论代表作 第二次因果革命即将到来?因果推断会是下一个AI热潮吗?本书全面阐述了现代因果关系分析,展示了因果关系如何从一个模糊的概念发展成为一套数学理论,并广泛用于统计学、人工智能、经济学、哲学、认知科学、卫生科学和社会学等领域。本书第1版曾获2001年拉卡托斯奖,作者朱迪亚·珀尔是2011年图灵奖得主。本书的出版将有利于中国的广大学者、学生和各领域研究人员了解和掌握因果模型、推理和推断相关的内容,在相关领域做出优异的成果。 ———————————————— 版权声明:本文为CSDN博主「AI科技大本营」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/dQCFKyQDXYm3F8rB0/article/details/127116130
-
Hello_RPA双击编辑后怎么返回
-
关闭studio后出现报错页面,但不影响使用,询问出现这个页面有没有什么影响
-
请问各位大佬,bearpi-hm-micro可以做外接摄像头模块吗?可以后面搞深度学习吗?
-
❤ AI系列往期直播回顾:【GDE直播公开课·第七期】低门槛AI开发模式:ModelFoundry【GDE直播公开课 · 第十一期】AI如何举一反三——迁移学习技术洞察❤视频回顾videovideovideo❤ 精选问答序号问题回复1大模型在业务上的实践效果怎样,能不能举个例子?以NLP领域中文纠错举例,我们采用MacBERT大模型,在开源的数据集上做了纠错预训练任务(训练1-epoch大约15小时),再在业务数据上做了微调,最后纠错准确率从原来的75%提高到90%,性能大幅提升。2预训练模型的基础训练数据来源渠道有哪些?有什么标准和要求?主要来源是业界开源的数据集,目前开源数据集的规模已经很大,完全适用于科学研究。当然如果是针对特定领域,还是需要通过相关合作来获取,或从网络查找对应词条来收集。本身预训练的目的就是节约标注成本,因此数据而言只要和业务数据类型保证一致即可,当然在此基础上做一些数据处理、清洗、去噪等也是可以的。3这么多预训练方法,我们应该在什么场景下用哪个?还是具体问题具体分析,首先看业务需求的侧重点,如果不考虑资源成本,只追求准确率等性能,那可以选择尝试那些更大的模型;如果资源受限,比如端侧业务,那需要选择更轻量化的模型。4运营商业务结构化数据,后期是否可以尝试大模型?结构化数据的大模型在学术界其实一直有在研究,不过还未有大规模应用,还是需要有更多的突破点。5预训练小模型有前途吗?在大模型快速发展以来,基于预训练小模型的迁移学习一直都是AI领域的中坚力量。这两者是并存关系,在某些领域小模型甚至更优。比如人脸识别领域,对推理时延的实时性要求非常高,这是小模型天然的优势所在。6请问地址补全用的预训练模型是什么?就是基本的BERT-base模型。7构建神经网络模型结构,初始状态下如何确定backbone结构?还是遵循从简到难的过程,可以先尝试经典的ResNet等网络结构,再对比一些transformer-based网络结构,如ViT、Swin-transformer等。8会有细分领域的大模型么?细分领域或者说垂直领域的大模型一直都有,比如电商领域大模型E-BERT、金融领域大模型FinBERT等。9如果用现有的大模型,训练特定的语料,比如中医病历,能否直接给出诊断呢?病历诊断这种生成类任务,目前还有很大的发展空间。个人认为可以作为辅助诊断,暂时还不能用来做直接诊断。10NLP大模型在哪些领域有应用?跨语言应用是NLP大模型最好的发挥场景之一,因为存在样本量很少的语言,比如跨语言机器翻译、跨语言文本分类等;同时NLP大模型在基于知识图谱的推荐、检索、问答等都有很好的应用。另外生成类任务也是NLP大模型发力的方向,能够实现智能创作、人机交互等应用。11请问跨模态的大模型,除了艺术设计类(封面、艺术品等)的文生图还有其他的可落地场景吗?个人看法,要实现强人工智能,跨模态是必须的。就目前而言,如电商领域的图文检索、自动驾驶中的人机交互、语音助手等都是可落地的场景。12想要了解CV大模型在现实生活中具体的应用场景有哪些?人脸识别算不算CV大模型中的场景,他在大模型中是怎么训练数据和提高识别的精度的?业内人脸识别技术应用现状和优劣势是什么,是不是都要用到AI和大模型的能力?人脸识别用了预训练的技术(比如对比学习范式,在无标注情况下怎么学习人脸),但目前不算大模型的场景,因为其对检测速度要求非常高,输出表征向量维度越小越好,不太合适大模型,小模型效果就已经很好很有效。活动说明1.有效盖楼:留言“报名”+“截图”、参与提问/建议或微信朋友圈点赞截图的,均可参与盖楼;2.无效盖楼:复制别人的提问、建议等,以及其他不符合要求的灌水信息皆为无效盖楼。注意:同一用户盖楼不能连续超过3楼,总楼层数不能超过10楼。超过盖楼数将视为无效盖楼。无效盖楼且踩中获奖楼层,也将视为无效,奖品不予发放,该楼层奖项轮空;3.盖楼总数及微信朋友圈点赞量取值仅限活动期间内,即2022年9月15日至9月27日24:00,其余时间不纳入计算范围;4.为保证活动有序进行,一经发现有作弊行为,将取消奖励资格;5.所有获奖用户,请于获奖后3日内完成实名认证,否则视为放弃奖励;6.请务必使用个人账号参与活动。本次活动如一个实名认证对应多个账号,只有一个账号可领取奖励;一个实名认证账号只能对应一个收件人,如同一账号填写多个不同收件人或不同账号填写同一收件人,均不予发放奖励;(举例说明:具备同一证件号(比如身份证号/护照ID/海外驾照ID/企业唯一识别号等)、同一手机号、同一设备、同一IP地址等,均视为同一实名用户)7.所有参加本活动的用户,均视为认可并同意遵守华为云社区的用户协议及隐私政策;8.GDE数智平台可能需要根据活动的实际举办情况对活动规则进行变更;若有变更,将以活动页面告知等方式及时通知;9.活动结束后将在活动帖和【GDE直播交流群】微信群中公布获奖名单,奖品配送范围为中国大陆地区,部分地区或因疫情原因延迟配送;10.GDE数智平台拥有活动解释权。中奖公示(已提供地址的中奖人员,奖品将陆续发出;未提供地址的,请留意私信,工作人员将联系获取地址,请在2022年10月21日前提供地址,过时视为自动放弃礼品)请各位中奖者微信添加:华为GDE官方小助手(gdezhushou),回复:GDE直播公开课提供邮寄地址,不添加不能获奖哦~小助手微信二维码报名有奖楼层昵称奖品5乌龟哥哥GDE定制鼠标垫13linghz666GDE定制鼠标垫20DragonCurryGDE定制鼠标垫27linghz666重复,每人仅一次获盖楼奖34Hello DiggerGDE定制鼠标垫探讨有奖昵称优秀提问奖品Hello DiggerNLP大模型在哪些领域有应用?GDE定制帆布袋madqfrog请问老师跨模态的大模型,除了艺术设计类(封面、艺术品等)的文生图还有其他的可落地场景么?GDE定制帆布袋分享有奖排名昵称奖品1linghz666GDE定制防晒伞2上帝之眼GDE定制防晒伞3乌龟哥哥GDE定制防晒伞直播互动奖轮次昵称奖品第一轮王*GDE定制玩偶第一轮李*宇GDE定制玩偶第一轮黄*国GDE定制玩偶第二轮王*GDE定制T恤视频号幸运福袋幸运福袋昵称奖品1A服装鞋子GDE定制防晒伞2LpcGDE定制防晒伞3Tayu Jonathan 明泽GDE定制防晒伞
-
1 线性回归线性回归(Linear Regression)可能是最流行的机器学习算法。线性回归就是要找一条直线,并且让这条直线尽可能地拟合散点图中的数据点。它试图通过将直线方程与该数据拟合来表示自变量(x 值)和数值结果(y 值)。然后就可以用这条线来预测未来的值!这种算法最常用的技术是最小二乘法(Least of squares)。这个方法计算出最佳拟合线,以使得与直线上每个数据点的垂直距离最小。总距离是所有数据点的垂直距离(绿线)的平方和。其思想是通过最小化这个平方误差或距离来拟合模型。例如,简单线性回归,它有一个自变量(x 轴)和一个因变量(y 轴)。2 逻辑回归逻辑回归(Logistic regression)与线性回归类似,但它是用于输出为二进制的情况(即,当结果只能有两个可能的值)。对最终输出的预测是一个非线性的 S 型函数,称为 logistic function, g()。这个逻辑函数将中间结果值映射到结果变量 Y,其值范围从 0 到 1。然后,这些值可以解释为 Y 出现的概率。S 型逻辑函数的性质使得逻辑回归更适合用于分类任务。逻辑回归曲线图,显示了通过考试的概率与学习时间的关系。3 决策树决策树(Decision Trees)可用于回归和分类任务。在这一算法中,训练模型通过学习树表示(Tree representation)的决策规则来学习预测目标变量的值。树是由具有相应属性的节点组成的。在每个节点上,我们根据可用的特征询问有关数据的问题。左右分支代表可能的答案。最终节点(即叶节点)对应于一个预测值。每个特征的重要性是通过自顶向下方法确定的。节点越高,其属性就越重要。决定是否在餐厅等候的决策树示例。4 朴素贝叶斯朴素贝叶斯(Naive Bayes)是基于贝叶斯定理。它测量每个类的概率,每个类的条件概率给出 x 的值。这个算法用于分类问题,得到一个二进制“是 / 非”的结果。看看下面的方程式。朴素贝叶斯分类器是一种流行的统计技术,可用于过滤垃圾邮件!5 支持向量机(SVM)支持向量机(Support Vector Machine,SVM)是一种用于分类问题的监督算法。支持向量机试图在数据点之间绘制两条线,它们之间的边距最大。为此,我们将数据项绘制为 n 维空间中的点,其中,n 是输入特征的数量。在此基础上,支持向量机找到一个最优边界,称为超平面(Hyperplane),它通过类标签将可能的输出进行最佳分离。超平面与最近的类点之间的距离称为边距。最优超平面具有最大的边界,可以对点进行分类,从而使最近的数据点与这两个类之间的距离最大化。例如,H1 没有将这两个类分开。但 H2 有,不过只有很小的边距。而 H3 以最大的边距将它们分开了。6 K- 最近邻算法(KNN)K- 最近邻算法(K-Nearest Neighbors,KNN)非常简单。KNN 通过在整个训练集中搜索 K 个最相似的实例,即 K 个邻居,并为所有这些 K 个实例分配一个公共输出变量,来对对象进行分类。K 的选择很关键:较小的值可能会得到大量的噪声和不准确的结果,而较大的值是不可行的。它最常用于分类,但也适用于回归问题。用于评估实例之间相似性的距离可以是欧几里得距离(Euclidean distance)、曼哈顿距离(Manhattan distance)或明氏距离(Minkowski distance)。欧几里得距离是两点之间的普通直线距离。它实际上是点坐标之差平方和的平方根。7 K- 均值K- 均值(K-means)是通过对数据集进行分类来聚类的。例如,这个算法可用于根据购买历史将用户分组。它在数据集中找到 K 个聚类。K- 均值用于无监督学习,因此,我们只需使用训练数据 X,以及我们想要识别的聚类数量 K。该算法根据每个数据点的特征,将每个数据点迭代地分配给 K 个组中的一个组。它为每个 K- 聚类(称为质心)选择 K 个点。基于相似度,将新的数据点添加到具有最近质心的聚类中。这个过程一直持续到质心停止变化为止。8 随机森林随机森林(Random Forest)是一种非常流行的集成机器学习算法。这个算法的基本思想是,许多人的意见要比个人的意见更准确。在随机森林中,我们使用决策树集成(参见决策树)。为了对新对象进行分类,我们从每个决策树中进行投票,并结合结果,然后根据多数投票做出最终决定。在训练过程中,每个决策树都是基于训练集的引导样本来构建的。在分类过程中,输入实例的决定是根据多数投票做出的。9 降维由于我们今天能够捕获的数据量之大,机器学习问题变得更加复杂。这就意味着训练极其缓慢,而且很难找到一个好的解决方案。这一问题,通常被称为“维数灾难”(Curse of dimensionality)。降维(Dimensionality reduction)试图在不丢失最重要信息的情况下,通过将特定的特征组合成更高层次的特征来解决这个问题。主成分分析(Principal Component Analysis,PCA)是最流行的降维技术。主成分分析通过将数据集压缩到低维线或超平面 / 子空间来降低数据集的维数。这尽可能地保留了原始数据的显著特征。可以通过将所有数据点近似到一条直线来实现降维的示例。10 人工神经网络(ANN)人工神经网络(Artificial Neural Networks,ANN)可以处理大型复杂的机器学习任务。神经网络本质上是一组带有权值的边和节点组成的相互连接的层,称为神经元。在输入层和输出层之间,我们可以插入多个隐藏层。人工神经网络使用了两个隐藏层。除此之外,还需要处理深度学习。人工神经网络的工作原理与大脑的结构类似。一组神经元被赋予一个随机权重,以确定神经元如何处理输入数据。通过对输入数据训练神经网络来学习输入和输出之间的关系。在训练阶段,系统可以访问正确的答案。如果网络不能准确识别输入,系统就会调整权重。经过充分的训练后,它将始终如一地识别出正确的模式。每个圆形节点表示一个人工神经元,箭头表示从一个人工神经元的输出到另一个人工神经元的输入的连接。
-
介绍一篇来自卡耐基梅隆大学等单位 ECCV 2022 的一篇关于快速知识蒸馏的文章,用基本的训练参数配置就可以把 ResNet-50 在 ImageNet-1K 从头开始 (from scratch) 训练到 80.1% (不使用 mixup,cutmix 等数据增强),训练速度(尤其是数据读取开销)相比传统分类框架节省 16% 以上,比之前 SOTA 算法快 30% 以上,是目前精度和速度双双最优的知识蒸馏策略之一,代码和模型已全部开源! 论文和项目网址:http://zhiqiangshen.com/projects/FKD/index.html 代码:https://github.com/szq0214/FKD知识蒸馏(KD)自从 2015 年由 Geoffrey Hinton 等人提出之后,在模型压缩,视觉分类检测等领域产生了巨大影响,后续产生了无数相关变种和扩展版本,但是大体上可以分为以下几类:vanilla KD,online KD,teacher-free KD 等。最近不少研究表明,一个最简单、朴素的知识蒸馏策略就可以获得巨大的性能提升,精度甚至高于很多复杂的 KD 算法。但是 vanilla KD 有一个不可避免的缺点:每次 iteration 都需要把训练样本输入 teacher 前向传播产生软标签 (soft label),这样就导致很大一部分计算开销花费在了遍历 teacher 模型上面,然而 teacher 的规模通常会比 student 大很多,同时 teacher 的权重在训练过程中都是固定的,这样就导致整个知识蒸馏框架学习效率很低。针对这个问题,本文首先分析了为何没法直接为每张输入图片产生单个软标签向量然后在不同 iterations 训练过程中复用这个标签,其根本原因在于视觉领域模型训练过程数据增强的使用,尤其是 random-resize-cropping 这个图像增强策略,导致不同 iteration 产生的输入样本即使来源于同一张图片也可能来自不同区域的采样,导致该样本跟单个软标签向量在不同 iterations 没法很好的匹配。本文基于此,提出了一个快速知识蒸馏的设计,通过特定的编码方式来处理需要的参数,继而进一步存储复用软标签(soft label),与此同时,使用分配区域坐标的策略来训练目标网络。通过这种策略,整个训练过程可以做到显式的 teacher-free,该方法的特点是既快(16%/30% 以上训练加速,对于集群上数据读取缓慢的缺点尤其友好),又好(使用 ResNet-50 在 ImageNet-1K 上不使用额外数据增强可以达到 80.1% 的精度)。
-
初学者,按照HiQ教程测试了“基于Jupyter Notebook开发量子神经网络对鸢尾花进行分类”部分测试,发生如下错误求教,谢谢!
上滑加载中
推荐直播
-
DTT年度收官盛典:华为开发者空间大咖汇,共探云端开发创新
2025/01/08 周三 16:30-18:00
Yawei 华为云开发工具和效率首席专家 Edwin 华为开发者空间产品总监
数字化转型进程持续加速,驱动着技术革新发展,华为开发者空间如何巧妙整合鸿蒙、昇腾、鲲鹏等核心资源,打破平台间的壁垒,实现跨平台协同?在科技迅猛发展的今天,开发者们如何迅速把握机遇,实现高效、创新的技术突破?DTT 年度收官盛典,将与大家共同探索华为开发者空间的创新奥秘。
去报名 -
GaussDB应用实战:手把手带你写SQL
2025/01/09 周四 16:00-18:00
Steven 华为云学堂技术讲师
本期直播将围绕数据库中常用的数据类型、数据库对象、系统函数及操作符等内容展开介绍,帮助初学者掌握SQL入门级的基础语法。同时在线手把手教你写好SQL。
去报名
热门标签