返回顶部
首页 > 资讯 > 后端开发 > Python >人脸老化预测(Python)
  • 934
分享到

人脸老化预测(Python)

python开发语言 2023-09-05 13:09:51 934人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

本次项目的文件 main.py主程序如下 导入必要的库和模块: 导入 Tensorflow 库以及自定义的 FaceAging 模块。导入操作系统库和参数解析库。 定义 str2bool 函数: 自定义函数用于将字符串转换为布尔

本次项目的文件

main.py主程序如下

  1. 导入必要的库和模块:

  2. 定义 str2bool 函数:

    • 自定义函数用于将字符串转换为布尔值。
  3. 创建命令行参数解析器:

    • 使用 argparse.ArgumentParser 创建解析器,设置命令行参数的相关信息,如是否训练、轮数、数据集名称等。
  4. 主函数 main(_) 入口:

    • 打印设置的参数。
    • 配置 TensorFlow 会话,设置 GPU 使用等。
  5. with tf.Session(config=config) as session 中:

    • 创建 FaceAging 模型实例,传入会话、训练模式标志、保存路径和数据集名称。
  6. 判断是否训练模式:

    • 如果是训练模式,根据参数决定是否使用预训练模型进行训练。
    • 如果不使用预训练模型,执行预训练步骤,并在预训练完成后开始正式训练。
    • 执行模型的训练方法,传入训练轮数等参数。
  7. 如果不是训练模式:

    • 进入测试模式,执行模型的自定义测试方法,传入测试图像目录。
  8. __name__ == '__main__' 中执行程序:

    • 执行命令行参数解析和主函数。
import tensorflow as tffrom FaceAging import FaceAging  # 导入自定义的 FaceAging 模块from os import environimport argparse# 设置环境变量,控制 TensorFlow 输出日志等级environ['TF_CPP_MIN_LOG_LEVEL'] = '3'# 自定义一个函数用于将字符串转换为布尔值def str2bool(v):    if v.lower() in ('yes', 'true', 't', 'y', '1'):        return True    elif v.lower() in ('no', 'false', 'f', 'n', '0'):        return False    else:        raise argparse.ArgumentTypeError('Boolean value expected.')# 创建命令行参数解析器parser = argparse.ArgumentParser(description='CAAE')parser.add_argument('--is_train', type=str2bool, default=True, help='是否进行训练')parser.add_argument('--epoch', type=int, default=50, help='训练的轮数')parser.add_argument('--dataset', type=str, default='UTKFace', help='存储在./data目录中的训练数据集名称')parser.add_argument('--savedir', type=str, default='save', help='保存检查点、中间训练结果和摘要的目录')parser.add_argument('--testdir', type=str, default='None', help='测试图像所在的目录')parser.add_argument('--use_trained_model', type=str2bool, default=True, help='是否使用已有的模型进行训练')parser.add_argument('--use_init_model', type=str2bool, default=True, help='如果找不到已有模型,是否从初始模型开始训练')FLAGS = parser.parse_args()# 主函数入口def main(_):    # 打印设置参数    import pprint    pprint.pprint(FLAGS)    # 配置 TensorFlow 会话    config = tf.ConfigProto()    config.gpu_options.allow_growth = True    with tf.Session(config=config) as session:        # 创建 FaceAging 模型实例        model = FaceAging(            session,  # TensorFlow 会话            is_training=FLAGS.is_train,  # 是否为训练模式的标志            save_dir=FLAGS.savedir,  # 保存检查点、样本和摘要的路径            dataset_name=FLAGS.dataset  # 存储在 ./data 目录中的数据集名称        )        if FLAGS.is_train:            print ('\n\t训练模式')            if not FLAGS.use_trained_model:                print ('\n\t预训练网络')                model.train(                    num_epochs=10,  # 训练轮数                    use_trained_model=FLAGS.use_trained_model,                    use_init_model=FLAGS.use_init_model,                    weights=(0, 0, 0)                )                print ('\n\t预训练完成!训练将开始。')            model.train(                num_epochs=FLAGS.epoch,  # 训练轮数                use_trained_model=FLAGS.use_trained_model,                use_init_model=FLAGS.use_init_model            )        else:            print ('\n\t测试模式')            model.custom_test(                testing_samples_dir=FLAGS.testdir + '/*jpg'            )if __name__ == '__main__':    # 在主程序中执行命令行解析和执行主函数    tf.app.run()

 

FaceAging.py

主要流程

  1. 导入必要的库和模块:

    • 导入所需的python库,如NumPy、TensorFlow等。
    • 导入自定义的操作(ops.py)。
  2. 定义 FaceAging 类:

    • 在初始化方法中,设置了模型的各种参数,例如输入图像大小、网络层参数、训练参数等,并创建了 TensorFlow 图的输入节点。
    • 定义了图的结构,包括编码器、生成器、判别器等。
    • 定义了损失函数,包括生成器、判别器、总变差(TV)等。
    • 收集了需要用于TensorBoard可视化的摘要信息。
  3. train 方法:

    • 从文件中加载训练数据集的文件名列表。
    • 定义了优化器和损失函数,然后进行模型的训练。
    • 在每个epoch中,随机选择一部分训练图像样本,计算并更新生成器和判别器的参数,输出训练进度等信息。
    • 保存模型的中间检查点,生成样本图像用于可视化,训练结束后保存最终模型。
  4. encoder 方法:

    • 实现了编码器结构,将输入图像转化为对应的噪声或特征。
  5. generator 方法:

    • 实现了生成器结构,将噪声特征、年龄标签和性别标签拼接,生成相应年龄段的人脸图像。
  6. discriminator_zdiscriminator_img 方法:

    • 实现了判别器结构,对输入的噪声特征或图像进行判别。
  7. save_checkpointload_checkpoint 方法:

    • 用于保存和加载训练过程中的模型检查点。
  8. sampletest 方法:

    • 生成一些样本图像以及将训练过程中的中间结果保存为图片。
  9. custom_test 方法:

    • 运行模型进行自定义测试,加载模型并生成特定人脸的年龄化效果。
from __future__ import divisionimport osimport timefrom glob import globimport tensorflow as tfimport numpy as npfrom scipy.io import savematfrom ops import *class FaceAging(object):    def __init__(self,                 session,  # TensorFlow session                 size_image=128,  # size the input images                 size_kernel=5,  # size of the kernels in convolution and deconvolution                 size_batch=100,  # mini-batch size for training and testing, must be square of an integer                 num_input_channels=3,  # number of channels of input images                 num_encoder_channels=64,  # number of channels of the first conv layer of encoder                 num_z_channels=50,  # number of channels of the layer z (noise or code)                 num_categories=10,  # number of categories (age segments) in the training dataset                 num_gen_channels=1024,  # number of channels of the first deconv layer of generator                 enable_tile_label=True,  # enable to tile the label                 tile_ratio=1.0,  # ratio of the length between tiled label and z                 is_training=True,  # flag for training or testing mode                 save_dir='./save',  # path to save checkpoints, samples, and summary                 dataset_name='UTKFace'  # name of the dataset in the folder ./data                 ):        self.session = session        self.image_value_range = (-1, 1)        self.size_image = size_image        self.size_kernel = size_kernel        self.size_batch = size_batch        self.num_input_channels = num_input_channels        self.num_encoder_channels = num_encoder_channels        self.num_z_channels = num_z_channels        self.num_categories = num_categories        self.num_gen_channels = num_gen_channels        self.enable_tile_label = enable_tile_label        self.tile_ratio = tile_ratio        self.is_training = is_training        self.save_dir = save_dir        self.dataset_name = dataset_name        # ************************************* input to graph ********************************************************        self.input_image = tf.placeholder(            tf.float32,            [self.size_batch, self.size_image, self.size_image, self.num_input_channels],            name='input_images'        )        self.age = tf.placeholder(            tf.float32,            [self.size_batch, self.num_categories],            name='age_labels'        )        self.gender = tf.placeholder(            tf.float32,            [self.size_batch, 2],            name='gender_labels'        )        self.z_prior = tf.placeholder(            tf.float32,            [self.size_batch, self.num_z_channels],            name='z_prior'        )        # ************************************* build the graph *******************************************************        print ('\n\tBuilding graph ...')        # encoder: input image --> z        self.z = self.encoder(            image=self.input_image        )        # generator: z + label --> generated image        self.G = self.generator(            z=self.z,            y=self.age,            gender=self.gender,            enable_tile_label=self.enable_tile_label,            tile_ratio=self.tile_ratio        )        # discriminator on z        self.D_z, self.D_z_logits = self.discriminator_z(            z=self.z,            is_training=self.is_training        )        # discriminator on G        self.D_G, self.D_G_logits = self.discriminator_img(            image=self.G,            y=self.age,            gender=self.gender,            is_training=self.is_training        )        # discriminator on z_prior        self.D_z_prior, self.D_z_prior_logits = self.discriminator_z(            z=self.z_prior,            is_training=self.is_training,            reuse_variables=True        )        # discriminator on input image        self.D_input, self.D_input_logits = self.discriminator_img(            image=self.input_image,            y=self.age,            gender=self.gender,            is_training=self.is_training,            reuse_variables=True        )        # ************************************* loss functions *******************************************************        # loss function of encoder + generator        #self.EG_loss = tf.nn.l2_loss(self.input_image - self.G) / self.size_batch  # L2 loss        self.EG_loss = tf.reduce_mean(tf.abs(self.input_image - self.G))  # L1 loss        # loss function of discriminator on z        self.D_z_loss_prior = tf.reduce_mean(            tf.nn.sigmoid_cross_entropy_with_logits(logits=self.D_z_prior_logits, labels=tf.ones_like(self.D_z_prior_logits))        )        self.D_z_loss_z = tf.reduce_mean(            tf.nn.sigmoid_cross_entropy_with_logits(logits=self.D_z_logits, labels=tf.zeros_like(self.D_z_logits))        )        self.E_z_loss = tf.reduce_mean(            tf.nn.sigmoid_cross_entropy_with_logits(logits=self.D_z_logits, labels=tf.ones_like(self.D_z_logits))        )        # loss function of discriminator on image        self.D_img_loss_input = tf.reduce_mean(            tf.nn.sigmoid_cross_entropy_with_logits(logits=self.D_input_logits, labels=tf.ones_like(self.D_input_logits))        )        self.D_img_loss_G = tf.reduce_mean(            tf.nn.sigmoid_cross_entropy_with_logits(logits=self.D_G_logits, labels=tf.zeros_like(self.D_G_logits))        )        self.G_img_loss = tf.reduce_mean(            tf.nn.sigmoid_cross_entropy_with_logits(logits=self.D_G_logits, labels=tf.ones_like(self.D_G_logits))        )        # total variation to smooth the generated image        tv_y_size = self.size_image        tv_x_size = self.size_image        self.tv_loss = (            (tf.nn.l2_loss(self.G[:, 1:, :, :] - self.G[:, :self.size_image - 1, :, :]) / tv_y_size) +            (tf.nn.l2_loss(self.G[:, :, 1:, :] - self.G[:, :, :self.size_image - 1, :]) / tv_x_size)) / self.size_batch        # *********************************** trainable variables ****************************************************        trainable_variables = tf.trainable_variables()        # variables of encoder        self.E_variables = [var for var in trainable_variables if 'E_' in var.name]        # variables of generator        self.G_variables = [var for var in trainable_variables if 'G_' in var.name]        # variables of discriminator on z        self.D_z_variables = [var for var in trainable_variables if 'D_z_' in var.name]        # variables of discriminator on image        self.D_img_variables = [var for var in trainable_variables if 'D_img_' in var.name]        # ************************************* collect the summary ***************************************        self.z_summary = tf.summary.histogram('z', self.z)        self.z_prior_summary = tf.summary.histogram('z_prior', self.z_prior)        self.EG_loss_summary = tf.summary.Scalar('EG_loss', self.EG_loss)        self.D_z_loss_z_summary = tf.summary.scalar('D_z_loss_z', self.D_z_loss_z)        self.D_z_loss_prior_summary = tf.summary.scalar('D_z_loss_prior', self.D_z_loss_prior)        self.E_z_loss_summary = tf.summary.scalar('E_z_loss', self.E_z_loss)        self.D_z_logits_summary = tf.summary.histogram('D_z_logits', self.D_z_logits)        self.D_z_prior_logits_summary = tf.summary.histogram('D_z_prior_logits', self.D_z_prior_logits)        self.D_img_loss_input_summary = tf.summary.scalar('D_img_loss_input', self.D_img_loss_input)        self.D_img_loss_G_summary = tf.summary.scalar('D_img_loss_G', self.D_img_loss_G)        self.G_img_loss_summary = tf.summary.scalar('G_img_loss', self.G_img_loss)        self.D_G_logits_summary = tf.summary.histogram('D_G_logits', self.D_G_logits)        self.D_input_logits_summary = tf.summary.histogram('D_input_logits', self.D_input_logits)        # for saving the graph and variables        self.saver = tf.train.Saver(max_to_keep=2)    def train(self,              num_epochs=200,  # number of epochs              learning_rate=0.0002,  # learning rate of optimizer              beta1=0.5,  # parameter for Adam optimizer              decay_rate=1.0,  # learning rate decay (0, 1], 1 means no decay              enable_shuffle=True,  # enable shuffle of the dataset              use_trained_model=True,  # use the saved checkpoint to initialize the network              use_init_model=True,  # use the init model to initialize the network              weigts=(0.0001, 0, 0)  # the weights of adversarial loss and TV loss              ):        # *************************** load file names of images ******************************************************        file_names = glob(os.path.join('./data', self.dataset_name, '*.jpg'))        size_data = len(file_names)        np.random.seed(seed=2017)        if enable_shuffle:            np.random.shuffle(file_names)        # *********************************** optimizer **************************************************************        # over all, there are three loss functions, weights may differ from the paper because of different datasets        self.loss_EG = self.EG_loss + weigts[0] * self.G_img_loss + weigts[1] * self.E_z_loss + weigts[2] * self.tv_loss # slightly increase the params        self.loss_Dz = self.D_z_loss_prior + self.D_z_loss_z        self.loss_Di = self.D_img_loss_input + self.D_img_loss_G        # set learning rate decay        self.EG_global_step = tf.Variable(0, trainable=False, name='global_step')        EG_learning_rate = tf.train.exponential_decay(            learning_rate=learning_rate,            global_step=self.EG_global_step,            decay_steps=size_data / self.size_batch * 2,            decay_rate=decay_rate,            staircase=True        )        # optimizer for encoder + generator        with tf.variable_scope('opt', reuse=tf.AUTO_REUSE):            self.EG_optimizer = tf.train.AdamOptimizer(                learning_rate=EG_learning_rate,                beta1=beta1            ).minimize(                loss=self.loss_EG,                global_step=self.EG_global_step,                var_list=self.E_variables + self.G_variables            )            # optimizer for discriminator on z            self.D_z_optimizer = tf.train.AdamOptimizer(                learning_rate=EG_learning_rate,                beta1=beta1            ).minimize(                loss=self.loss_Dz,                var_list=self.D_z_variables            )            # optimizer for discriminator on image            self.D_img_optimizer = tf.train.AdamOptimizer(                learning_rate=EG_learning_rate,                beta1=beta1            ).minimize(                loss=self.loss_Di,                var_list=self.D_img_variables            )        # *********************************** tensorboard *************************************************************        # for visualization (TensorBoard): $ tensorboard --logdir path/to/log-directory        self.EG_learning_rate_summary = tf.summary.scalar('EG_learning_rate', EG_learning_rate)        self.summary = tf.summary.merge([            self.z_summary, self.z_prior_summary,            self.D_z_loss_z_summary, self.D_z_loss_prior_summary,            self.D_z_logits_summary, self.D_z_prior_logits_summary,            self.EG_loss_summary, self.E_z_loss_summary,            self.D_img_loss_input_summary, self.D_img_loss_G_summary,            self.G_img_loss_summary, self.EG_learning_rate_summary,            self.D_G_logits_summary, self.D_input_logits_summary        ])        self.writer = tf.summary.FileWriter(os.path.join(self.save_dir, 'summary'), self.session.graph)        # ************* get some random samples as testing data to visualize the learning process *********************        sample_files = file_names[0:self.size_batch]        file_names[0:self.size_batch] = []        sample = [load_image(            image_path=sample_file,            image_size=self.size_image,            image_value_range=self.image_value_range,            is_gray=(self.num_input_channels == 1),        ) for sample_file in sample_files]        if self.num_input_channels == 1:            sample_images = np.array(sample).astype(np.float32)[:, :, :, None]        else:            sample_images = np.array(sample).astype(np.float32)        sample_label_age = np.ones(            shape=(len(sample_files), self.num_cateGories),            dtype=np.float32        ) * self.image_value_range[0]        sample_label_gender = np.ones(            shape=(len(sample_files), 2),            dtype=np.float32        ) * self.image_value_range[0]        for i, label in enumerate(sample_files):            label = int(str(sample_files[i]).split('/')[-1].split('_')[0])            if 0 <= label <= 5:                label = 0            elif 6 <= label <= 10:                label = 1            elif 11 <= label <= 15:                label = 2            elif 16 <= label <= 20:                label = 3            elif 21 <= label <= 30:                label = 4            elif 31 <= label <= 40:                label = 5            elif 41 <= label <= 50:                label = 6            elif 51 <= label <= 60:                label = 7            elif 61 <= label <= 70:                label = 8            else:                label = 9            sample_label_age[i, label] = self.image_value_range[-1]            gender = int(str(sample_files[i]).split('/')[-1].split('_')[1])            sample_label_gender[i, gender] = self.image_value_range[-1]        # ******************************************* training *******************************************************        # initialize the graph        tf.global_variables_initializer().run()        # load check point        if use_trained_model:            if self.load_checkpoint():                print("\tSUCCESS ^_^")            else:                print("\tFAILED >__

 3.data,一共23708张照片 

 4.对数据集感兴趣的可以关注

from __future__ import divisionimport osimport timefrom glob import globimport tensorflow as tfimport numpy as npfrom scipy.io import savematfrom ops import *#https://mbd.pub/o/bread/ZJ2UmJpp

来源地址:https://blog.csdn.net/qq_40840797/article/details/132397169

--结束END--

本文标题: 人脸老化预测(Python)

本文链接: https://www.lsjlt.com/news/395373.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 人脸老化预测(Python)
    本次项目的文件 main.py主程序如下 导入必要的库和模块: 导入 TensorFlow 库以及自定义的 FaceAging 模块。导入操作系统库和参数解析库。 定义 str2bool 函数: 自定义函数用于将字符串转换为布尔...
    99+
    2023-09-05
    python 开发语言
  • Python实现笑脸检测+人脸口罩检测功能
    目录一、人脸图像特征提取方法二、对笑脸数据集genki4k进行训练和测试(包括SVM、CNN),输出模型训练精度和测试精度(F1-score和ROC),实现检测图片笑脸和实时视频笑脸...
    99+
    2024-04-02
  • Python实现对照片中的人脸进行颜值预测
    一、所需工具 **Python版本:**3.5.4(64bit) 二、相关模块 opencv_python模块 sklearn模块 numpy模块 ...
    99+
    2024-04-02
  • Python视频人脸检测识别
    案例 这里我们还是使用 opencv 中自带了 haar人脸特征分类器,通过读取一段视频来识别其中的人脸。 代码实现:   动图有点花,讲究着看吧:   如果是捕捉摄像头,只需要改变以下代码即可: cap = cv2.Vi...
    99+
    2023-01-31
    视频 Python
  • 人脸检测实战终极之OpenCV+Python实现人脸对齐
    目录前言实现面部矫正器导入必要的包对齐人脸展示结果前言 这篇博文的目的是演示如何使用 OpenCV、Python 和面部标志对齐人脸。 给定一组面部标志(输入坐标),我们的目标是将图...
    99+
    2024-04-02
  • Python人脸检测实战之疲劳检测
    目录使用 OpenCV 构建犯困检测器测试疲劳检测器今天我们实现疲劳检测。 如果眼睛已经闭上了一段时间,我们会认为他们开始打瞌睡并发出警报来唤醒他们并引起他们的注意。我们测试一段视频...
    99+
    2024-04-02
  • Python中怎么实现人脸检测
    Python中怎么实现人脸检测,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。首先需要安装这些包,以Ubuntu为例:$ sudo apt-g...
    99+
    2023-06-17
  • Python人脸识别之微笑检测
    目录一.实验准备二.图片预处理三.划分数据集四.CNN提取人脸识别笑脸和非笑脸1.创建模型2.归一化处理3.数据增强4.创建网络5.单张图片测试6.摄像头实时测试五.Dlib提取人脸...
    99+
    2024-04-02
  • python基于Opencv实现人脸口罩检测
    一、开发环境 python 3.6.6 opencv-python 4.5.1 二、设计要求 1、使用opencv-python对人脸口罩进行检测 三、设计原理 设计流程图如图3-1...
    99+
    2024-04-02
  • Python+MediaPipe实现检测人脸功能详解
    目录MediaPipe概述人脸检测MediaPipe概述 谷歌开源MediaPipe于2019年6月首次推出。它的目标是通过提供一些集成的计算机视觉和机器学习功能,使我们的生活变得轻...
    99+
    2024-04-02
  • python实现人脸检测的简单实例
    目录OpenCV代码结果:方法如下:完整代码:总结OpenCV OpenCV 是计算机视觉领域最受欢迎的开源库,起初它由 C/C ++ 编写,现在用 Python 也能使用。 Ope...
    99+
    2024-04-02
  • Python实现检测照片中的人脸数
    目录1、准备2、代码3、效果最近疫情被隔离在家,准备研究一下python的机器学习,看了一些资料。也逛了逛论坛。 机器学习的实例真是太多了,让人眼花缭乱,更加懵逼了。通俗来说,主要两...
    99+
    2024-04-02
  • 如何在python中使用OpenCV检测人脸
    这期内容当中小编将会给大家带来有关如何在python中使用OpenCV检测人脸,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Python的优点有哪些1、简单易用,与C/C++、Java、C# 等传统语言相...
    99+
    2023-06-14
  • python实现人脸检测的实例分析
    这篇文章主要介绍“python实现人脸检测的实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“python实现人脸检测的实例分析”文章能帮助大家解决问题。OpenCVOpenCV 是计算机视觉领...
    99+
    2023-06-29
  • Python怎么实现人脸识别微笑检测
    这篇文章主要介绍“Python怎么实现人脸识别微笑检测”,在日常操作中,相信很多人在Python怎么实现人脸识别微笑检测问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python怎么实现人脸识别微笑检测”的疑...
    99+
    2023-06-21
  • 怎么用Python+MediaPipe实现检测人脸功能
    这篇文章主要介绍“怎么用Python+MediaPipe实现检测人脸功能”,在日常操作中,相信很多人在怎么用Python+MediaPipe实现检测人脸功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用...
    99+
    2023-06-29
  • 人脸检测——基于Flask和PaddleHub
    目录 前言 分析与设计 实现 1. 部署人脸检测模型 2. 使用Flask构建app2.1 目录结构2.2 forms.py2.3 utils.py2.4 app.py2.5 ind...
    99+
    2023-03-23
    基于Flask和PaddleHub 人脸检测
  • Python 人脸识别 OpenCV (
    ■环境Python 3.6.0Pycharm 2017.1.3 ■库、库的版本OpenCV 3.4.1 (cp36) ■haarcascades下载https://github.com/opencv/opencv/tree/master/d...
    99+
    2023-01-31
    Python OpenCV
  • python神经网络facenet人脸检测及keras实现
    目录什么是facenetInception-ResNetV11、Stem的结构:2、Inception-resnet-A的结构:3、Inception-resnet-B的结构:4、I...
    99+
    2024-04-02
  • 使用Python快速实现简单的人脸检测
    最近有个比较要好的朋友问我能不能从监控视频里识别到从监控跟前经过的指定的人。因为他们单位的监控室经常要花大量的人力跟时间去找某个人在哪个位置出现过的证据。听起来像是一份比较有挑战性的任务,就答应他试试看。 先理一下思路,首先要做的工作是从...
    99+
    2023-01-31
    的人 快速 简单
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作