pytorch记录
创始人
2025-05-28 10:08:28
0

张量

张量如同数组和矩阵一样, 是一种特殊的数据结构。在PyTorch中, 神经网络的输入、输出以及网络的参数等数据, 都是使用张量来进行描述。

张量的使用和Numpy中的ndarrays很类似, 区别在于张量可以在GPU或其它专用硬件上运行, 这样可以得到更快的加速效果。

初始化

# 1.直接生成张量
data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)# 2.Numpy数组来生成张量
np_array = np.array(data)
x_np = torch.from_numpy(np_array)# 3.已有的张量来生成新的张量
# 新的张量将继承已有张量的数据属性(结构、类型), 也可以重新指定新的数据类型x_ones = torch.ones_like(x_data)   # 保留 x_data 的属性
print(f"Ones Tensor: \n {x_ones} \n")x_rand = torch.rand_like(x_data, dtype=torch.float)   # 重写 x_data 的数据类型int -> float
print(f"Random Tensor: \n {x_rand} \n")
#显示
Ones Tensor:tensor([[1, 1],[1, 1]])Random Tensor:tensor([[0.0381, 0.5780],[0.3963, 0.0840]])# 4.通过指定数据维度来生成张量
shape = (2,3,) # shape是元组类型, 用来描述张量的维数
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")
Random Tensor:tensor([[0.0266, 0.0553, 0.9843],[0.0398, 0.8964, 0.3457]])Ones Tensor:tensor([[1., 1., 1.],[1., 1., 1.]])Zeros Tensor:tensor([[0., 0., 0.],[0., 0., 0.]])

张量属性

从张量属性我们可以得到张量的维数、数据类型以及它们所存储的设备(CPU或GPU)。

tensor = torch.rand(3,4)print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")输出:
Shape of tensor: torch.Size([3, 4])   # 维数
Datatype of tensor: torch.float32     # 数据类型
Device tensor is stored on: cpu       # 存储设备

运算

有超过100种张量相关的运算操作, 例如转置、索引、切片、数学运算、线性代数、随机采样等
https://pytorch.org/docs/stable/torch.html

# 1.判断当前环境GPU是否可用, 然后将tensor导入GPU内运行
if torch.cuda.is_available():tensor = tensor.to('cuda')# 2.张量的索引和切片
tensor = torch.ones(4, 4)
tensor[:,1] = 0            # 将第1列(从0开始)的数据全部赋值为0
print(tensor)
# 输出:
tensor([[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.]])# 3.张量的拼接
t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(t1)
tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])# 4.张量的乘积和矩阵乘法
# 逐个元素相乘结果
print(f"tensor.mul(tensor): \n {tensor.mul(tensor)} \n")
# 等价写法:
print(f"tensor * tensor: \n {tensor * tensor}")
tensor.mul(tensor):tensor([[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.]])tensor * tensor:tensor([[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.]])
# 张量与张量的矩阵乘法
print(f"tensor.matmul(tensor.T): \n {tensor.matmul(tensor.T)} \n")
# 等价写法:
print(f"tensor @ tensor.T: \n {tensor @ tensor.T}")
tensor.matmul(tensor.T):tensor([[3., 3., 3., 3.],[3., 3., 3., 3.],[3., 3., 3., 3.],[3., 3., 3., 3.]])tensor @ tensor.T:tensor([[3., 3., 3., 3.],[3., 3., 3., 3.],[3., 3., 3., 3.],[3., 3., 3., 3.]])
# 5.自动赋值运算
# 自动赋值运算通常在方法后有 _ 作为后缀, 例如: x.copy_(y), x.t_()操作会改变 x 的取值。
# 自动赋值运算虽然可以节省内存, 但在求导时会因为丢失了中间过程而导致一些问题, 所以我们并不鼓励使用它。
print(tensor, "\n")
tensor.add_(5)
print(tensor)
tensor([[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.]])tensor([[6., 5., 6., 6.],[6., 5., 6., 6.],[6., 5., 6., 6.],[6., 5., 6., 6.]])

Tensor与Numpy的转化

张量和Numpy array数组在CPU上可以共用一块内存区域, 改变其中一个另一个也会随之改变。

# 1. 由张量变换为Numpy array数组
t = torch.ones(5)
print(f"t: {t}")
n = t.numpy()
print(f"n: {n}")
t: tensor([1., 1., 1., 1., 1.])
n: [1. 1. 1. 1. 1.]# 修改张量的值,则Numpy array数组值也会随之改变
t.add_(1)
print(f"t: {t}")
print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.])
n: [2. 2. 2. 2. 2.]# 2.由Numpy array数组转为张量
n = np.ones(5)
t = torch.from_numpy(n)
# 修改Numpy array数组的值,则张量值也会随之改变。
np.add(n, 1, out=n)
print(f"t: {t}")
print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
n: [2. 2. 2. 2. 2.]

torch.norm()

https://pytorch.org/docs/stable/generated/torch.norm.html#torch.norm

torch.norm(input, p='fro', dim=None, keepdim=False, out=None, dtype=None)1
  • input (Tensor):输入张量。它的数据类型必须是浮点数或复数类型。
  • p (int, float, inf, -inf, ‘fro’, ‘nuc’, optional):范数计算中的幂指数值。默认为’fro’
  • dim:指定计算范数的输入维度。如果 dim 为 None,则将在输入的所有维度上计算范数。如果 p 表示的范数类型不支持指定的维数,则会发生错误

torch.cat

# 
feature = torch.cat(feature,-1)

torch.range和torch.arange

torch.range(start=1, end=6) 的结果是会包含end的,
而torch.arange(start=1, end=6)的结果并不包含end。
两者创建的tensor的类型也不一样

>>> y=torch.range(1,6)
>>> y
tensor([1., 2., 3., 4., 5., 6.])
>>> y.dtype
torch.float32>>> z=torch.arange(1,6)
>>> z
tensor([1, 2, 3, 4, 5])
>>> z.dtype
torch.int64

在pytorch中view函数的作用为重构张量的维度,相当于numpy中resize()的功能,但是用法可能不太一样

torch.nn

Conv2d

class Conv2d(_ConvNd):# 初始化函数,这里主要了解有哪些参数传进来就可以了def __init__(self,in_channels: int,out_channels: int,kernel_size: _size_2_t,stride: _size_2_t = 1,padding: _size_2_t = 0,dilation: _size_2_t = 1,groups: int = 1,bias: bool = True,padding_mode: str = 'zeros'  # TODO: refine this type):#————————————————看到这就可以了————————————————————kernel_size = _pair(kernel_size)stride = _pair(stride)padding = _pair(padding)dilation = _pair(dilation)super(Conv2d, self).__init__(in_channels, out_channels, kernel_size, stride, padding, dilation,False, _pair(0), groups, bias, padding_mode)def _conv_forward(self, input, weight):if self.padding_mode != 'zeros':return F.conv2d(F.pad(input, self._reversed_padding_repeated_twice, mode=self.padding_mode),weight, self.bias, self.stride,_pair(0), self.dilation, self.groups)return F.conv2d(input, weight, self.bias, self.stride,self.padding, self.dilation, self.groups)# 前向传播计算def forward(self, input: Tensor) -> Tensor:return self._conv_forward(input, self.weight)

Conv2d是一个类,它包含了做卷积运算所需要的参数(__init__函数),以及卷积操作(forward函数)

一共九个参数,一般用前三个就可以处理一般的任务:

  • in_channels :输入通道数目
  • out_channels :输出通道数目,当前层的输入通道数就是上一层卷积的输出通道数,当前层的输出通道数需要自己指定
  • kernel_size :卷积核大小,如果输入是一个值,比如 3,那么卷积核大小就是 3 × 3 ,如果不想卷积核宽和高相等,还可以输入tuple类型数据,比如: ( 3 , 5 )
  • stride :步长大小,跟上面卷积核参数一样,如果输入是一个值,比如 2 ,步长就是 2×2 ,还可以输入元组 ( 2 , 1 ) ,表示卷积核每次向右移动 1个步长,向下移动 2 个步长。
  • padding :填充,参数表示在周围补0的情况。补0的方向为上、下、左、右四个方向。如果是输入是单个值,比如1,就是在上下左右四个方向补一圈0。如果输入是元组比如 (2,1) ,表示在上下两个方向各补两行0,在左右两个方向各补一列0。
  • dilation :进行扩展卷积需要的参数,目的是扩大感受野,捕获多尺度上下文信息
  • groups :进行分组卷积需要的参数。(有需要自行深入了解)
  • bias :偏置,布尔类型,默认为 True ,即增加一个学习的偏置项。
  • padding_mode :填充的模式,默认是 zero ,还可以选择 reflect 、 replicate 、 circular

Linear

nn.linear()是用来设置网络中的全连接层的,而在全连接层中的输入与输出都是二维张量,一般形状为[batch_size, size],与卷积层要求输入输出是4维张量不同

CLASS torch.nn.Linear(in_feature,out_feature,bias=True)
- in_feature:
import torch
import torch.nn as nn
import torch.nn.functional as Fclass Net(nn.Module):def __init__(self):super(Net, self).__init__()# 1 input image channel, 6 output channels, 5x5 square convolution# kernel# batch_size,输入通道数,图像高宽self.conv1 = nn.Conv2d(1, 6, 5)self.conv2 = nn.Conv2d(6, 16, 5)# an affine operation: y = Wx + bself.fc1 = nn.Linear(16 * 5 * 5, 120)  # 5*5 from image dimensionself.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10)def forward(self, x):# Max pooling over a (2, 2) windowx = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))# If the size is a square, you can specify with a single numberx = F.max_pool2d(F.relu(self.conv2(x)), 2)x = torch.flatten(x, 1) # flatten all dimensions except the batch dimensionx = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return xnet = Net()
print(net)

contiguous

contiguous 本身是形容词,表示连续的,关于 contiguous,PyTorch 提供了is_contiguous、contiguous(形容词动用)两个方法 ,分别用于判定Tensor是否是 contiguous 的,以及保证Tensor是contiguous的。

is_contiguous直观的解释是Tensor底层一维数组元素的存储顺序与Tensor按行优先一维展开的元素顺序是否一致

forward

模型训练时,不需要使用forward,只要在实例化一个对象中传入对应的参数就可以自动调用 forward 函数

class Module(nn.Module):def __init__(self):super(Module, self).__init__()# ......def forward(self, x):# ......return x
data = ..... #输入数据
# 实例化一个对象
module = Module()
# 前向传播
module(data) 
# 而不是使用下面的
# module.forward(data) 

DataLoader

torch.utils.data.DataLoader
数据加载器:结合数据集和采样器,并在数据集上提供单进程或多进程迭代器。

参数:

  • dataset:要加载的数据
  • batch_size(int, 可选):每批加载的样本数
  • shuffle(bool, 可选):默认false,是否让数据重新洗牌
  • sampler:定义从数据集中抽取样本的策略。如果指定,shuffle必须为 False
  • batch_sampler (Sampler, 可选): 类似sampler,但一次返回一批索引。与 batch_size、shuffle、sampler 和 drop_last 互斥。
  • num_workers(int, 可选):用于数据加载的子进程数。 0 表示数据将在主进程中加载​​,默认0
  • collat​​e_fn(callable, 可选):合并样本列表以形成小批量。
  • pin_memory (bool, 可选)::如果为 True,数据加载器将在返回之前将张量复制到 CUDA 固定内存中
  • drop_last (bool, 可选):如果数据集大小不能被批次大小整除,则设为True以丢弃最后一个不完整的批次。如果设为 False 并且数据集的大小不能被批大小整除,那么最后一批将更小,默认:false
  • timeout(numeric,可选):如果为正,则从工人收集批次的超时值。应始终为非负数,默认值0
  • worker_init_fn(callable,可选):如果不是None,这将在传播之后和数据加载之前,以worker id作为输入,在每个worker子进程上调用, 默认None

    默认情况下,每个 worker 都将其 PyTorch 种子设置为“base_seed + worker_id”,其中“base_seed”是主进程使用其 RNG 生成的 long。 但是,其他库的种子可能会在初始化工作人员(例如 NumPy)时被复制,导致每个工作人员返回相同的随机数。
    (请参阅常见问题解答中的 dataloader-workers-random-seed 部分。)您可以使用 torch.initial_seed() 访问 :attr:`worker_init_fn 中每个工人的 PyTorch 种子,并使用它 在数据加载之前设置其他种子

register_buffer

nn.modules.module.py
Adds a persistent buffer to the module.向模块添加持久缓冲区。This is typically used to register a buffer that should not to beconsidered a model parameter. For example, BatchNorm's ``running_mean``is not a parameter, but is part of the persistent state.这通常用于注册不应被视为模型参数的缓冲区。例如,BatchNorm的“running_mean”不是参数,而是持久状态的一部分。Buffers can be accessed as attributes using given names.
缓冲区可以使用给定的名称作为属性访问。 Args:name (string): name of the buffer. The buffer can be accessedfrom this module using the given name 名称(字符串):缓冲区的名称。可以使用给定的名称从该模块访问缓冲区tensor (Tensor): buffer to be registered.Example::>>> self.register_buffer('running_mean', torch.zeros(num_features))        

pytorch一般情况下,是将网络中的参数保存成orderedDict形式的,这里的参数其实包含两种,一种是模型中各种module含的参数,即nn.Parameter,我们当然可以在网络中定义其他的nn.Parameter参数,另一种就是buffer,前者每次optim.step会得到更新,而不会更新后者。

tqdm

Tqdm 是一个快速,可扩展的Python进度条,可以在 Python 长循环中添加一个进度提示信息,用户只需要封装任意的迭代器 tqdm(iterator)

namedtuple

https://blog.csdn.net/kongxx/article/details/51553362

单机多卡并行训练

https://zhuanlan.zhihu.com/p/86441879?ivk_sa=1024320u

平衡DataParallel带来的显存使用不平衡:官方给的解决方案就是使用 DistributedDataParallel来代替 DataParallel

因为DistributedDataParallel比DataParallel运行的更快, 然后显存分屏的更加均衡. 而且DistributedDataParallel功能更加强悍, 例如分布式的模型(一个模型太大, 以至于无法放到一个GPU上运行, 需要分开到多个GPU上面执行). 只有DistributedDataParallel支持分布式的模型像单机模型那样可以进行多机多卡的运算.

torch.clamp_min

方法设置一个下限min,tensor中有元素小于这个值, 就把对应的值赋为min

torch.split

torch.split()作用将tensor分成块结构。

torch.split(tensor, ssplit_size_or_section, dim=0)

参数:

  • tesnor:input,待分输入

  • split_size_or_sections:需要切分的大小(int or list )

  • dim:切分维度

  • output:切分后块结构

当split_size_or_sections为int时,tenor结构和split_size_or_sections,正好匹配,那么ouput就是大小相同的块结构。如果按照split_size_or_sections结构,tensor不够了,那么就把剩下的那部分做一个块处理。

当split_size_or_sections 为list时,那么tensor结构会一共切分成len(list)这么多的小块,每个小块中的大小按照list中的大小决定,其中list中的数字总和应等于该维度的大小,否则会报错(注意这里与split_size_or_sections为int时的情况不同)。

学习率调整-torch.optim.lr_scheduler

https://zhuanlan.zhihu.com/p/580253389

lr_scheduler.StepLR

torch.optim.lr_scheduler 模块提供了一些根据 epoch 训练次数来调整学习率(learning rate)的方法。一般情况下我们会设置随着 epoch 的增大而逐渐减小学习率从而达到更好的训练效果。

CLASStorch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1, verbose=False)

参数:

  • optimizer (Optimizer) – Wrapped optimizer.

  • step_size (int) – Period of learning rate decay.学习率下降间隔数,若为30,则会在30、60、90…个step时,将学习率调整为lr*gamma。gamma (float) – Multiplicative factor of learning rate decay. Default: 0.1. 学习率调整倍数,默认为0.1倍,即下降10倍。

  • last_epoch (int) – The index of last epoch. Default: -1.上一个epoch数,这个变量用来指示学习率是否需要调整。当last_epoch符合设定的间隔时,就会对学习率进行调整。当为-1时,学习率设置为初始值。

  • verbose (bool) – If True, prints a message to stdout for each update. Default: False.

lr_scheduler.MultiStepLR

lr_scheduler.ExponentialLR

lr_scheduler.CosineAnnealingLR

lr_scheduler.ReduceLROnPlateau

模型保存

torch.save与torch.load

(1)官方推荐方法

#第一种:只存储模型中的参数,该方法速度快,占用空间少(官方推荐使用)
model = VGGNet()
torch.save(model.state_dict(), PATH)          #存储model中的参数new_model = VGGNet()                          #建立新模型
new_model.load_state_dict(torch.load(PATH))   #将model中的参数加载到new_model中#第二种:存储整个模型
model = VGGNet()
# save会把当前目录结构以及py文件class都写入模型中保存下来,于是当把pt文件迁移到其他项目中使用,而其他项目的关于模型相关的目录结构有所变化,就会报no module named models的错误了
torch.save(model, PATH)                       #存储整个模型new_model = torch.load(PATH)                  #将整个model加载到new_model中
#new_model 不再需要第一种方法中的建立新模型的步骤'''
关于上面表达式中PATH参数的说明:
PATH参数是你保存文件的路径,并且需要指定保存文件的文件名,如:
torch.save(model, '/home/user/save_model/checkpoint.pth')
即将该模型保存在/home/user/save_model路径下的checkpoint.pth文件中,保存的文件格式约定为.pth或.pt
new_model = torch.load('/home/user/save_model/checkpoint.pth')但是在pytorch1.6版本中,torch.save存储的文件格式采用了新的基于压缩文件的格式 .pth.tar
torch.load依然保留了加载了旧格式.pth的能力
'''

推荐的方式是将·state_dict保存下来,state_dict相当于训练结果中的权重和各种参数,这样在加载时不会受到目录和class名等等的限制

torch.save(my_model.state_dict(), PATH)
model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH))
model.eval()

(2)保存checkpoint(检查点)

通常在训练模型的过程中,可能会遭遇断电、断网的尴尬,一旦出现这种情况,先前训练的模型就白费了,又得重头开始训练。因此每隔一段时间就将训练模型信息保存一次很有必要。而这些信息不光包含模型的参数信息,还包含其他信息,如当前的迭代次数,优化器的参数等,以便用于后面恢复训练。

state = {'epoch' : epoch + 1,  # 保存当前的迭代次数'state_dict' : model.state_dict(), # 保存模型参数'optimizer' : optimizer.state_dict(), # 保存优化器参数...,      # 其余一些想保持的参数都可以添加进来...,
}torch.save(state, 'checkpoint.pth.tar')     # 将state中的信息保存到checkpoint.pth.tar
# Pytorch 约定使用.tar格式来保存这些检查点# 当想恢复训练时
checkpoint = torch.load('checkpoint.pth.tar')
epoch = checkpoint['epoch']
model.load_state_dict(checkpoint['state_dict'])   # 加载模型的参数
optimizer.load_state_dict(checkpoint['optimizer']) # 加载优化器的参数

3)不同设备上的模型存储与加载

#1、在CPU上存储模型,在GPU上加载模型
#CPU存储
torch.save(model.state_dict(), PATH)
#GPU加载
device = torch.device('cuda')
model = Model()
model.load_state_dict(torch.load(PATH, map_location='cuda:0')) #可以选择任意GPU设备
model.to(device)----------------------------------------------------------------------------------
#2、在GPU上存储,CPU上加载
#GPU存储
torch.save(model.state_dict(), PATH)
#CPU加载
device = torch.device('cpu')
model = Model()
model.load_state_dict(torch.load(PATH, map_location=device))----------------------------------------------------------------------------------
#3、在GPU上存储,在GPU上加载
#GPU存储
torch.save(model.state_dict(), PATH)
#GPU加载
device = torch.device('cuda')
model = Model()
model.load_state_dict(torch.load(PATH))
model.to(device)----------------------------------------------------------------------------------
#4、存储和加载使用过torch.nn.DataParallel的模型#(1)多卡训练,单卡加载部署'''
这种情况要防止参数保存的时候没有加module,那么保存的参数名称是module.conv1.weight,
而单卡的参数名称是conv1.weight,这时就会报错,找不到相应的字典的错误。
此时可以通过手动的方式删减掉模型中前几位的名称,然后重新加载。
不懂代码可以先看一下第2部分内容模型参数存储内容解析
'''model = torch.nn.DataParallel(model)
#存储
torch.save(model.module.state_dict(), PATH)
#加载
kwargs={'map_location':lambda storage, loc: storage.cuda(gpu_id)}
def load_GPUS(model,model_path,kwargs):state_dict = torch.load(PATH, **kwargs)# create new OrderedDict that does not contain 'module.'from collections import OrderedDictnew_state_dict = OrderedDict()for k, v in state_dict.items():name = k[7:] # remove 'module.'new_state_dict[name] = v# load paramsmodel.load_state_dict(new_state_dict)return model#(2)单卡训练,多卡加载部署'''
此时唯有记住一点,因为单卡训练参数是没有module的,而多卡加载的参数是有module的,
因此需要保证参数加载在模型分发之前。
'''#存储
torch.save(model.state_dict(), PATH)
#加载
model.load_state_dict(torch.load(PATH))
model = torch.nn.DataParallel(model)     #模型分发#(3)多卡训练,多卡加载部署'''
环境如果没有变化,则可以直接加载,如果环境有变化,则可以拆解成第1种情况,然后再分发模型。
'''

(4)模型变更后的参数加载操作

当我们使用像resnet50、resnet101这样的网络时,通常可以从网上对应下载到这些模型的预训练参数文件,但是我们所使用的模型,可能需要在resnet50或resnet101网络上进行一些修改,比如增加一些结构,或者删除一些结构。所以我们只希望加载修改后的模型与原来的模型之间具有相同结构部分的参数。

#假设下载到的原有模型参数文件为checkpoint.pth.tar
model = OurModel()
model_checkpoint = torch.load('checkpoint.pth.tar')
pretrain_model_dict = model_checkpoint['state_dict']
model_dict = model.state_dict

torch.jit.save与torch.jit.load

# 注意torch.jit.save保存的时torchscript模型,所以要先进行转换
scripted_module = torch.jit.script(MyModule())
torch.jit.save(scripted_module, 'mymodule.pt')
torch.jit.load('mymodule.pt')

torch.nn.Module

torch.nn.Module模块中的state_dict变量存放训练过程中需要学习的权重和偏执系数,state_dict作为python的字典对象将每一层的参数映射成tensor张量,需要注意的是torch.nn.Module模块中的state_dict只包含卷积层和全连接层的参数,当网络中存在batchnorm时,例如vgg网络结构,torch.nn.Module模块中的state_dict也会存放batchnorm’s running_mean。

相关内容

热门资讯

寿司郎怎么这么狂? 订阅 快刀财经 ▲ 做您的私人商学院多靠同行衬托。作者:半佛仙人来源:半佛仙人(ID:banfoSB...
上任仅两个月,众泰汽车62岁董... 红星资本局12月29日消息,今日晚间,众泰汽车(000980.SZ)公告称,公司董事长李立忠因个人家...
今年股价大涨近1900%,大牛... 12月29日晚,上纬新材公告称,公司股票自2025年7月9日至12月29日累计上涨1598.33%,...
痛别!吴锋院士逝世 ◎ 科技日报记者 张盖伦 12月29日,记者从北京理工大学了解到,中国工程院院士、著名材料科学家、我...
金价新高也不慌?资管机构认可黄... 全文共3234字,阅读全文约需7分钟随着金价的不断走高,黄金在资产配置中的角色日益被国内资管机构所关...
锂矿龙头突发公告:涉嫌内幕交易... 赣锋锂业(002460.SZ)今日公告称,公司于当日收到宜春市公安局的移送起诉告知书, 因涉嫌内幕交...
AI芯片主线熄火后,这一板块有... 临近年底,资金本以为是“刀枪入库、马放南山”的节奏;但没想到是市场依旧有小的热点出现,整体市场也没有...
减肥药的风卷到了宠物领域!华东... 宠物也有专属减肥药了,还是双靶点。12月29日,华东医药(000963)对外宣布称,12月26日,全...
870万罚款创三年之最,重庆农... 作者 | 刘银平编辑 | 付影来源 | 独角金融近日,重庆农商行(601077.SH)因5项违规行为...
目录价格超82亿美元!空客获国... 空客斩获国内航司A320系列大单。12月29日晚间,吉祥航空(603885.SH)发布公告称,拟与空...