当前位置: 首页 > 编程日记 > 正文

无人驾驶汽车系统入门:基于VoxelNet的激光雷达点云车辆检测及ROS实现

640?wx_fmt=jpeg

作者 | 申泽邦(Adam Shan)

兰州大学在读硕士研究生,主要研究方向无人驾驶,深度学习;兰大未来计算研究院无人车团队负责人,自动驾驶全栈工程师。


之前我们提到使用SqueezeSeg进行了三维点云的分割,由于采用的是SqueezeNet作为特征提取网络,该方法的处理速度相当迅速(在单GPU加速的情况下可达到100FPS以上的效率),然而,该方法存在如下的问题:


  • 第一,虽然采用了CRF改进边界模糊的问题,但是从实践结果来看,其分割的精度仍然偏低;

  • 第二,该模型需要大量的训练集,而语义分割数据集标注困难,很难获得大规模的数据集。当然,作者在其后的文章:SqueezeSegV2: Improved Model Structure and Unsupervised Domain Adaptation for Road-Object Segmentation from a LiDAR Point Cloud 中给出了改进的方案,我将在后面的文章中继续解读。需要注意的是,在无人车环境感知问题中,很多情况下并不需要对目标进行精确的语义分割,只需将目标以一个三维的Bounding Box准确框出即可(即Detection)。


本文介绍一种基于点云的Voxel(三维体素)特征的深度学习方法,实现对点云中目标的准确检测,并提供一个简单的ROS实现,供大家参考。


VoxelNet结构


VoxelNet是一个端到端的点云目标检测网络,和图像视觉中的深度学习方法一样,其不需要人为设计的目标特征,通过大量的训练数据集,即可学习到对应的目标的特征,从而检测出点云中的目标,如下:


640?wx_fmt=png


VoxelNet的网络结构主要包含三个功能模块:

(1)特征学习层;

(2)卷积中间层;

(3) 区域提出网络( Region Proposal Network,RPN)。


特征学习网络


特征学习网络的结构如下图所示,包括体素分块(Voxel Partition),点云分组(Grouping),随机采样(Random Sampling),多层的体素特征编码(Stacked Voxel Feature Encoding),稀疏张量表示(Sparse Tensor Representation)等步骤,具体来说:


640?wx_fmt=png


体素分块


这是点云操作里最常见的处理,对于输入点云,使用相同尺寸的立方体对其进行划分,我们使用一个深度、高度和宽度分别为(D,H,W)的大立方体表示输入点云,每个体素的深高宽为(vD,vH,vW) ,则整个数据的三维体素化的结果在各个坐标上生成的体素格(voxel grid)的个数为:640?wx_fmt=png


点云分组


将点云按照上一步分出来的体素格进行分组,如上图所示。


随机采样


很显然,按照这种方法分组出来的单元会存在有些体素格点很多,有些格子点很少的情况,64线的激光雷达一次扫描包含差不多10万个点,全部处理需要的计算力和内存都很高,而且高密度的点势必会给神经网络的计算结果带来偏差。所以,该方法在这里插入了一层随机采样,对于每一个体素格,随机采样固定数目的点,T 。


多个体素特征编码(Voxel Feature Encoding,VFE)层


之后是多个体素特征编码层,简称为VFE层,这是特征学习的主要网络结构,以第一个VFE层为例说明:


640?wx_fmt=png


对于输入:


640?wx_fmt=png


是一个体素格内随机采样的点集,640?wx_fmt=png分别点的XYZ坐标以及激光束的反射强度(即intensity),我们首先计算体素内所有点的平均值 (vx,vy,vz) 作为体素格的形心(类似于Voxel Grid Filter),那么我们就可以将体素格内所有点的特征数量扩充为如下形式:


640?wx_fmt=png

接着,每一个640?wx_fmt=png都会通过一个全连接网络(Fully Connected,FC,论文中用的是FCN来简称,实际上FCN更多的被用于表示全卷积网络,所以原文此处用FCN简称实际上不妥)被映射到一个特征空间640?wx_fmt=png,输入的特征维度为7,输出的特征维数变成m mm,全连接层包含了一个线性映射层,一个批标准化(Batch Normalization),以及一个非线性运算(ReLU),得到逐点的(point-wise)的特征表示。


接着我们采用最大池化(MaxPooling)对上一步得到的特征表示进行逐元素的聚合,这一池化操作是对元素和元素之间进行的,得到局部聚合特征(Locally Aggregated Feature),即640?wx_fmt=png ,最后,将逐点特征和逐元素特征进行连接(concatenate),得到输出的特征集合:


640?wx_fmt=png


对于所有的非空的体素格我们都进行上述操作,并且它们都共享全连接层(FC)的参数。我们使用符号640?wx_fmt=png来描述经过VFE以后特征的维数变化,那么显然全连接层的参数矩阵大小为:


640?wx_fmt=png


由于VFE层中包含了逐点特征和逐元素特征的连接,经过多层VFE以后,我们希望网络可以自动学习到每个体素内的特征表示(比如说体素格内的形状信),那么如何学习体素内的特征表示呢?原论文的方法下图所示:


640?wx_fmt=png


通过对体素格内所有点进行最大池化,得到一个体素格内特征表示 C 。


稀疏张量表示


通过上述流程处理非空体素格,我们可以得到一系列的体素特征(Voxel Feature)。这一系列的体素特征可以使用一个4维的稀疏张量来表示:


640?wx_fmt=png


虽然一次lidar扫描包含接近10万个点,但是超过90%的体素格都是空的,使用稀疏张量来描述非空体素格在于能够降低反向传播时的内存和计算消耗。


对于具体的车辆检测问题,我们取沿着Lidar坐标系的(Z,Y,X) (Z,Y,X)(Z,Y,X)方向取[−3,1]×[−40,40]×[0,70.4] [−3, 1] × [−40, 40] × [0, 70.4][−3,1]×[−40,40]×[0,70.4]立方体(单位为米)作为输入点云,取体素格的大小为:


640?wx_fmt=png


那么有


640?wx_fmt=png


我们设置随机采样的T=35 T = 35T=35,并且采用两个VFE层:VFE-1(7, 32) 和 VFE-2(32, 128),最后的全连接层将VFE-2的输出映射到640?wx_fmt=png 。最后,特征学习网络的输出即为一个尺寸为 (128×10×400×352) 的稀疏张量。整个特征网络的TensorFlow实现代码如下:


class VFELayer(object):

    def __init__(self, out_channels, name):
        super(VFELayer, self).__init__()
        self.units = int(out_channels / 2)
        with tf.variable_scope(name, reuse=tf.AUTO_REUSE) as scope:
            self.dense = tf.layers.Dense(
                self.units, tf.nn.relu, name='dense', _reuse=tf.AUTO_REUSE, _scope=scope)
            self.batch_norm = tf.layers.BatchNormalization(
                name='batch_norm', fused=True, _reuse=tf.AUTO_REUSE, _scope=scope)

    def apply(self, inputs, mask, training):
        # [K, T, 7] tensordot [7, units] = [K, T, units]
        pointwise = self.batch_norm.apply(self.dense.apply(inputs), training)

        #n [K, 1, units]
        aggregated = tf.reduce_max(pointwise, axis=1, keep_dims=True)

        # [K, T, units]
        repeated = tf.tile(aggregated, [1, cfg.VOXEL_POINT_COUNT, 1])

        # [K, T, 2 * units]
        concatenated = tf.concat([pointwise, repeated], axis=2)

        mask = tf.tile(mask, [112 * self.units])

        concatenated = tf.multiply(concatenated, tf.cast(mask, tf.float32))

        return concatenated


class FeatureNet(object):

    def __init__(self, training, batch_size, name=''):
        super(FeatureNet, self).__init__()
        self.training = training

        # scalar
        self.batch_size = batch_size
        # [ΣK, 35/45, 7]
        self.feature = tf.placeholder(
            tf.float32, [None, cfg.VOXEL_POINT_COUNT, 7], name='feature')
        # [ΣK]
        self.number = tf.placeholder(tf.int64, [None], name='number')
        # [ΣK, 4], each row stores (batch, d, h, w)
        self.coordinate = tf.placeholder(
            tf.int64, [None, 4], name='coordinate')

        with tf.variable_scope(name, reuse=tf.AUTO_REUSE) as scope:
            self.vfe1 = VFELayer(32'VFE-1')
            self.vfe2 = VFELayer(128'VFE-2')

        # boolean mask [K, T, 2 * units]
        mask = tf.not_equal(tf.reduce_max(
            self.feature, axis=2, keep_dims=True), 0)
        x = self.vfe1.apply(self.feature, mask, self.training)
        x = self.vfe2.apply(x, mask, self.training)

        # [ΣK, 128]
        voxelwise = tf.reduce_max(x, axis=1)

        # car: [N * 10 * 400 * 352 * 128]
        # pedestrian/cyclist: [N * 10 * 200 * 240 * 128]
        self.outputs = tf.scatter_nd(
            self.coordinate, voxelwise, [self.batch_size, 10, cfg.INPUT_HEIGHT, cfg.INPUT_WIDTH, 128])


卷积中间层


每一个卷积中间层包含一个3维卷积,一个BN层(批标准化),一个非线性层(ReLU),我们用:


640?wx_fmt=png


来描述一个卷积中间层,Conv3D表示是三维卷积,cin,cout分别表示输入和输出的通道数,k是卷积核的大小,它是一个向量,对于三维卷积而言,卷积核的大小为(k,k,k);s即stride,卷积操作的步长;p即padding,填充的尺寸。


对于车辆检测而言,设计的卷积中间层如下:


Conv3D(128, 64, 3,(2,1,1), (1,1,1))
Conv3D(64, 64, 3, (1,1,1), (0,1,1))
Conv3D(64, 64, 3, (2,1,1), (1,1,1))


卷积中间层的TensorFlow代码如下:


def ConvMD(M, Cin, Cout, k, s, p, input, training=True, activation=True, bn=True, name='conv'):
    temp_p = np.array(p)
    temp_p = np.lib.pad(temp_p, (11), 'constant', constant_values=(00))
    with tf.variable_scope(name) as scope:
        if(M == 2):
            paddings = (np.array(temp_p)).repeat(2).reshape(42)
            pad = tf.pad(input, paddings, "CONSTANT")
            temp_conv = tf.layers.conv2d(
                pad, Cout, k, strides=s, padding="valid", reuse=tf.AUTO_REUSE, name=scope)
        if(M == 3):
            paddings = (np.array(temp_p)).repeat(2).reshape(52)
            pad = tf.pad(input, paddings, "CONSTANT")
            temp_conv = tf.layers.conv3d(
                pad, Cout, k, strides=s, padding="valid", reuse=tf.AUTO_REUSE, name=scope)
        if bn:
            temp_conv = tf.layers.batch_normalization(
                temp_conv, axis=-1, fused=True, training=training, reuse=tf.AUTO_REUSE, name=scope)
        if activation:
            return tf.nn.relu(temp_conv)
        else:
            return temp_conv

# convolutinal middle layers
temp_conv = ConvMD(3128643, (211),
                    (111), self.input, name='conv1')
temp_conv = ConvMD(364643, (111),
                    (011), temp_conv, name='conv2')
temp_conv = ConvMD(364643, (211),
                    (111), temp_conv, name='conv3')
temp_conv = tf.transpose(temp_conv, perm=[02341])
temp_conv = tf.reshape(temp_conv, [-1, cfg.INPUT_HEIGHT, cfg.INPUT_WIDTH, 128])


区域提出网络(RPN)


RPN实际上是目标检测网络中常用的一种网络,下图是VoxelNet中使用的RPN:


640?wx_fmt=png


如图所示,该网络包含三个全卷积层块(Block),每个块的第一层通过步长为2的卷积将特征图采样为一半,之后是三个步长为1的卷积层,每个卷积层都包含BN层和ReLU操作。将每一个块的输出都上采样到一个固定的尺寸并串联构造高分辨率的特征图。最后,该特征图通过两种二维卷积被输出到期望的学习目标:


  • 概率评分图(Probability Score Map )

  • 回归图(Regression Map)


使用TensorFlow实现该RPN如下(非完整代码,完整代码请见文末链接)):


def Deconv2D(Cin, Cout, k, s, p, input, training=True, bn=True, name='deconv'):
    temp_p = np.array(p)
    temp_p = np.lib.pad(temp_p, (11), 'constant', constant_values=(00))
    paddings = (np.array(temp_p)).repeat(2).reshape(42)
    pad = tf.pad(input, paddings, "CONSTANT")
    with tf.variable_scope(name) as scope:
        temp_conv = tf.layers.conv2d_transpose(
            pad, Cout, k, strides=s, padding="SAME", reuse=tf.AUTO_REUSE, name=scope)
        if bn:
            temp_conv = tf.layers.batch_normalization(
                temp_conv, axis=-1, fused=True, training=training, reuse=tf.AUTO_REUSE, name=scope)
        return tf.nn.relu(temp_conv)

# rpn
# block1:
temp_conv = ConvMD(21281283, (22), (11),
                    temp_conv, training=self.training, name='conv4')
temp_conv = ConvMD(21281283, (11), (11),
                    temp_conv, training=self.training, name='conv5')
temp_conv = ConvMD(21281283, (11), (11),
                    temp_conv, training=self.training, name='conv6')
temp_conv = ConvMD(21281283, (11), (11),
                    temp_conv, training=self.training, name='conv7')
deconv1 = Deconv2D(1282563, (11), (00),
                    temp_conv, training=self.training, name='deconv1')

# block2:
temp_conv = ConvMD(21281283, (22), (11),
                    temp_conv, training=self.training, name='conv8')
temp_conv = ConvMD(21281283, (11), (11),
                    temp_conv, training=self.training, name='conv9')
temp_conv = ConvMD(21281283, (11), (11),
                    temp_conv, training=self.training, name='conv10')
temp_conv = ConvMD(21281283, (11), (11),
                    temp_conv, training=self.training, name='conv11')
temp_conv = ConvMD(21281283, (11), (11),
                    temp_conv, training=self.training, name='conv12')
temp_conv = ConvMD(21281283, (11), (11),
                    temp_conv, training=self.training, name='conv13')
deconv2 = Deconv2D(1282562, (22), (00),
                    temp_conv, training=self.training, name='deconv2')

# block3:
temp_conv = ConvMD(21282563, (22), (11),
                    temp_conv, training=self.training, name='conv14')
temp_conv = ConvMD(22562563, (11), (11),
                    temp_conv, training=self.training, name='conv15')
temp_conv = ConvMD(22562563, (11), (11),
                    temp_conv, training=self.training, name='conv16')
temp_conv = ConvMD(22562563, (11), (11),
                    temp_conv, training=self.training, name='conv17')
temp_conv = ConvMD(22562563, (11), (11),
                    temp_conv, training=self.training, name='conv18')
temp_conv = ConvMD(22562563, (11), (11),
                    temp_conv, training=self.training, name='conv19')
deconv3 = Deconv2D(2562564, (44), (00),
                    temp_conv, training=self.training, name='deconv3')

# final:
temp_conv = tf.concat([deconv3, deconv2, deconv1], -1)
# Probability score map, scale = [None, 200/100, 176/120, 2]
p_map = ConvMD(276821, (11), (00), temp_conv,
                training=self.training, activation=False, bn=False, name='conv20')
# Regression(residual) map, scale = [None, 200/100, 176/120, 14]
r_map = ConvMD(2768141, (11), (00),
                temp_conv, training=self.training, activation=False, bn=False, name='conv21')


损失函数

我们首先定义640?wx_fmt=png为正样本集合,640?wx_fmt=png为负样本集合,使用640?wx_fmt=png来表示一个真实的3D标注框,其中640?wx_fmt=png

表示标注框中心的坐标,640?wx_fmt=png表示标注框的长宽高,640?wx_fmt=png表示偏航角(Yaw)。相应的,640?wx_fmt=png表示正样本框。那么回归的目标为一下七个量:


640?wx_fmt=png


其中


640?wx_fmt=png


是正样本框的对角线。我们定义损失函数为:


640?wx_fmt=png



其中640?wx_fmt=png分别表示正样本640?wx_fmt=png和负样本640?wx_fmt=png的Softmax输出,640?wx_fmt=png分别表示神经网络的正样本输出的标注框和真实标注框。损失函数的前两项表示对于正样本输出和负样本输出的分类损失(已经进行了正规化),其中640?wx_fmt=png表示交叉熵,640?wx_fmt=png是两个常数,它们作为权重来平衡正负样本损失对于最后的损失函数的影响。640?wx_fmt=png表示回归损失,这里采用的是Smooth L1函数。


ROS实践


我们仍然使用第二十六篇博客的数据(截取自KITTI),下载地址:https://pan.baidu.com/s/1kxZxrjGHDmTt-9QRMd_kOA


我们直接采用qianguih提供的训练好的模型(参考:https://github.com/qianguih/voxelnet ,大家也可以基于该项目自己训练模型)。


安装项目依赖环境:


  • python3.5+

  • TensorFlow (tested on 1.4)

  • opencv

  • shapely

  • numba

  • easydict

  • ROS

  • jsk package


准备数据


下载上面的数据集,解压到项目(源码地址见文末)的data文件夹下,目录结构为:


data
----lidar_2d
--------0000...1.npy
--------0000...2.npy
--------.......


运行


  • catkin_make

  • roscd voxelnet/script/

  • python3 voxelnet_ros.py & python3 pub_kitti_point_cloud.py

注意不能使用rosrun,因为VoxelNet代码为Python 3.x


rqt节点图

640?wx_fmt=png


使用Rviz可视化


640?wx_fmt=png

640?wx_fmt=png


存在的问题


  • 实例的模型的性能不佳,由于论文作者没有开源其代码,许多参数仍然有待调整

  • 调整速度慢,没有实现作者提出的高效策略


感兴趣的同学可以试着调整参数提高模型性能,欢迎大家留言、私信交流。


源码地址:

https://github.com/AbangLZU/VoxelNetRos

数据地址:

https://pan.baidu.com/s/1kxZxrjGHDmTt-9QRMd_kOA

原文地址:

https://blog.csdn.net/AdamShan/article/details/84837211



2018 中国大数据技术大会

BDTC 2018

2018中国大数据技术大会今天在北京新云南正式拉开序幕,产学研大伽年度精彩分享,现场前沿观点频现,思维碰撞精彩迭起~~大会第一天精彩观点总结,分享给没有到会场的小伙伴们~(另外,目前大会官网已更新部分PPT,扫描海报二维码即可下载)

640?wx_fmt=jpeg

640?wx_fmt=jpeg

相关文章:

EX2010与EX2013共存迁移01-设计及说明

1.1共存条件说明 2013年之前发布的Exchange 2013版本是不支持共存的,只有在2013年4月2日发布的Exchange 2013 CU1版才支持共存,Exchange 2010必须为SP3版本才支持和2013共存及迁移,Exchange2003不支持和2013共存及迁移。下面是详细的共存说明…

linux ext4增加大小,如何修改 ext4 文件系统的大小

如何修改 ext4 文件系统的大小a. 扩大文件系统i启动到 Linux,umount 掉/dev/sdb1 和/dev/sdb2,若提示磁盘忙的话使用fuser 将正在使用磁盘的程序 kill 掉。(推荐使用另外的 Linux 启动盘来引导系统)ii使用 fdisk /dev/sdb 调整分区大小,进去之后,输入 p,记下要扩大分区起始位置…

Silverlight初级教程-开发工具

Silverlight初级教程 开发工具 在silverlight越来越流行的同时有很多的供应商开始筹划制作编辑和设计silverlight的工具。现在最常见的设计和开发工具是:Visual Studio 2008Visual Studio是微软整合的集成开发环境。截止此时Visual Studio 2008已经提供了编辑和预览…

201671010128 2017-11-12《Java程序设计》之图形程序设计

一、基本概念 Java的抽象窗口工具箱(Abstract Window Toolkit, AWT)包含在java.awt包中,它提供了许多用来设计GUI的组件类和容器类。AWT库处理用户界面元素的方法:把图形元素的创建和行为委托给本地GUI工具箱进行处理。应用AWT编写依赖于本地…

linux线程join的用法,join用法

Join用法- a 1显示第一个文件的不匹配行,- a 2为从第二个文件中显示不匹配行。n.m n为文件号,m为域号。1 . 3表示只显示文件1第三域,每个n,m必须用逗号分隔,如1 . 3,2 . 1。# cat name.txtM.Golls 12 Hi…

vss使用注意事项

连接方式 局域网方式连接 Internet 方式连接 在局域网方式连接时,需要输入自己的 vss 登陆帐号,账号可以通过管理器,自己在 vss 系统中注册; Internet 连接时默认使用的是 vss 中的 administrator 账号; 请大家都使用自…

沈向洋、黄学东等大咖助阵,IoT in Action微软深圳物联网大会即刻报名

每当海聊黑科技,总会有种恍然隔世的幻觉自动驾驶、无人配送、刷脸支付、智能翻译……物联网、人工智能、智能边缘等等新技术正在快速变得实用并普及怀疑论者还秉持观望,深怕技术布道之嫌而我们的现实中已经切实听见他们落地的声音因为“未来已经来临&…

centos6上以二进制方式安装mariadb5.5

准备mariadb-5.5.57-linux-x86_64.tar.gz二进制程序包 此包是经过编译的,也就是说我们要在特定的目录下安装; 步骤1、准备mysql用户 mkdir /app/data #此目录是存放mysql数据库、表的 useradd -r -m -d /app/data -s /sbin/nologin mysql #创建mysql用户…

“神人”or“闲人”?你的未来由AI与大数据决定

12 月 6 日,北京新云南皇冠假日酒店,由中国计算机学会主办,CCF 大数据专家委员会承办,CSDN、中科天玑数据科技股份有限公司协办的 2018 中国大数据技术大会(BDTC)首日议程圆满结束。本次大会为期三天&#…

linux 获取cpu id,linux获取cpu id和disk id

2013-04-19 15:17 57人阅读 评论(0)// 获得CPU IDpublic static final String CPU_ID_CMD "dmidecode -t 4 | grep ID |sort -u |awk -F: {print $2}";// 获得磁盘IDpublic static final String DISK_ID_CMD "fdisk -l |grep \"Disk identifier\" …

给gridview添加上下移动功能

给gridview添加上下移动功能存储过程代码:CREATE PROCEDURE [sp_trans_dept] now_id int,upside_id intASdeclare tmp_ordering int --临时变量declare sqlstr varchar(1000) --sql语句declare table_name varchar(500)declare column_name varchar(500)set t…

Lucene.Net 2.3.1开发介绍 —— 三、索引(六)

2.2 Field的Boost 如果说Document的Boost是一条线,那么Field的Boost则是一个点。怎么理解这个点呢?设置Document的Boost会影响所有字段。在搜索的过程中,一般至少会搜索两个Field,比如同时搜索标题和内容。而Document的Boost将同时…

linux nor flash 读写,9.2 NorFLASH读写实验——M25PExx

>[danger] 学习本节内容前,请先检查自己手上的开发板是否具备NorFlash存储器,如不具备则可跳过本章节。> ZigBee 标准板:具备> ZigBee MINI板:不具备> ZigBee 网关 & 嵌入式Linux 二合一开发板:具备我…

sql server分布式事务解决方案[新事务不能登记到指定的事务处理器中错误]

< DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd> 适用环境 操作系统&#xff1a;windows 2003&#xff0c;xp 数据库&#xff1a;sql server 2000/sql server 2005 使用链接服务器进行远程数据库访问的情况 一、 问题现象 在执行分布…

微软“叛变”谷歌 Chromium!

去年&#xff0c;微软工程师在公开演示 Azure 服务时&#xff0c;微软 Edge 浏览器频频崩溃&#xff0c;逼得他只能在众目睽睽的尴尬局面下&#xff0c;使用 Edge 下载 Chrome 浏览器来继续他的演示。一年之后的今天&#xff0c;Edge 就抱上了 Chrome 的大腿。图片来源&#xf…

vCenter Server Appliance 6.5 中重置丢失或忘记的 root 密码

vCenter Server Appliance 6.5 中重置丢失或忘记的 root 密码 目前安装vCenter Server Appliance 6.5客户原来越多&#xff0c;给用户配置过程中&#xff0c;往往会忽略默认的root 密码策略&#xff1a;60天过期。一旦密码过期或忘记密码&#xff0c;vcsa的管理控制台就无法通过…

linux 查看剪贴板历史,Clipboard History Manager插件,查看浏览器剪贴板历史记录

Clipboard History Manager插件&#xff0c;是一款浏览器剪贴板历史记录管理工具&#xff0c;通过它可以快速查看最多1000个本机上的剪贴数据&#xff0c;适用于Mac和Windows操作系统。A full-featured desktop clipboard manager for Mac, Windows and Linux to track what yo…

ORACLE执行计划的一些基本概念

本文介绍了ORACLE执行计划的一些基本概念&#xff0c;供学习应用。 一&#xff0e;相关的概念 Rowid的概念&#xff1a;rowid是一个伪列&#xff0c;既然是伪列&#xff0c;那么这个列就不是用户定义&#xff0c;而是系统自己给加上的。对每个表都有一个rowid的伪列&#xff0c…

公开课报名 | 那些年,我们在文本分类中遇到的坑

文本分类问题是企业在 NLP 领域中处理文本数据时经常会遇到的一个问题&#xff0c;很多时候&#xff0c;我们需要将文本信息进行分类&#xff0c;或提相关的接口以供外部进行文本上传&#xff0c;在针对于用户所上传的文档信息就需要进行文档内容的分类&#xff0c;那么针对于这…

Cisco网院成立10周年-未来三年在蓉增50所

2008年9月18日—— 今天&#xff0c;主题为“十年创新&#xff0c;传承未来”的Cisco中国网络技术学院十周年庆典在四川成都举行。会上&#xff0c;Cisco宣布将与四川省政府和教育部进一步加强合作&#xff0c;在四川新建立50所Cisco网络技术学院&#xff0c;以实现该项目在四川…

荣耀预装linux安装包,关于华为机子没有预装应用商店讨论

在荣耀笔记本(Linux版)中拥有深度应用商店&#xff0c;几步就搞定啦&#xff01;在荣耀笔记本(Linux版)中拥有深度应用商店&#xff0c;几步就搞定啦&#xff01;深度操作系统 今天随着预装深度操作系统(deepin)的荣耀笔记本(Linux版)的开卖(未来可期&#xff01;荣耀Magicbook…

如何自学CS?

整理 | 非主流出品 | AI科技大本营哪个行业的平均工资最高&#xff1f;计算机。国家统计局的数据显示&#xff0c;2016 年信息传输、软件和信息技术服务业年平均工资为 122478 元&#xff0c;首超金融行业&#xff0c;并于 2017 年再次夺魁。在互联网和人工智能浪潮的推动下&am…

oracle 使用nfs挂载的目录不能进行归档

oracle 使用nfs挂载的目录不能进行归档 在做实验时将oracle的归档目录放在nfs服务器上&#xff0c;启动数据库就会死掉&#xff0c;也不能进行归档。在报警日志中发现WARNING:NFS file system /mnt mounted with incorrect options WARNING:Expected NFS mount options: rs…

生产中NFS案例记录---写入权限解决过程

生产中NFS案例记录---写入权限解决过程NFS配置要求&#xff1a;1、 将oracle文件写入到NFS Server端&#xff0c;注意权限要与oracle端一致。2、 Oracle端目录文件所属用户为oracle&#xff0c;uid&#xff1a;500 gid 501。格式约定&#xff1a;命令显示过程 文字说明特别注意…

吴文俊人工智能科学技术奖:陆汝钤院士、百度王海峰等获奖

12月9日上午&#xff0c;被誉为“中国智能科学技术最高奖”的吴文俊人工智能科学技术奖在苏州举行颁奖典礼。本届吴文俊人工智能奖共对70项人工智能成果授奖。其中&#xff0c;中国科学院院士、中国科学院数学与系统科学研究院研究员陆汝钤成为首位吴文俊人工智能最高成就奖获得…

河南科技大学c语言章节作业答案,河南科技大学C语言试题

c语言试题,基本上是题库。上机作业用的。大家好好把握。C程序的运行环境和简单C源程序的调试&#xff0c;实验报告(共 题)&#xff0c;用时(127分33秒)&#xff0c;成绩(A)1、 有如下程序&#xff1a; #include"stdio.h" main( ) { int a8;printf("%d,%5d,%-5d#…

qinyu.blog.51cto.com里的好文章,比尔盖茨

世纪枭雄比尔盖茨的王者传奇儿时&#xff0c;他便躁动不安&#xff0c;顶着梳不顺的头发&#xff0c;在竞技中缕缕获胜。少年英才没有机会慢慢成长&#xff0c;21岁&#xff0c;他创办了微软&#xff0c;从此走上IT业的颠峰之路&#xff0c;垄断了13年的财富榜首&#xff1b;32…

Clean-Code: 注释

别给糟糕的代码加注释-----------------重新写吧 这是书中的关于注释一章的第一句话&#xff0c;怎么说呢&#xff0c;这句话个人感觉很对&#xff0c;但是实际上却很少这么做&#xff0c; 有几个原因&#xff1a; 糟糕的代码不是自己写的&#xff0c;别人写的代码&#xff0…

在c语言中,函数中的自动变量可以赋初值,每调用一次,赋一次初值,计算机二级考试 程序设计基础试题及答案三...

《程序设计基础》考试试卷三1. 判断下面标识符中哪个是C语言中合法的用户定义标识符&#xff1a;A. a-bB. #abdC. typedefD. _max2. …b?在内存中占个字节&#xff0c;“B”在内存中占个字节。A. 1B. 2C. 3D. 43. 下列表达式的值哪些不等于0&#xff1f;A. 2>>1B. ~a&am…

免费报名 | WPS专家教你文本分类在企业中的应用实践

文本分类问题是企业在 NLP 领域中处理文本数据时经常会遇到的一个问题&#xff0c;很多时候&#xff0c;我们需要将文本信息进行分类&#xff0c;或提相关的接口以供外部进行文本上传&#xff0c;在针对于用户所上传的文档信息就需要进行文档内容的分类&#xff0c;那么针对于这…