精华内容
下载资源
问答
  • 上一节我们自己写代码训练了只有一个神经元的反相器,它虽然只有一点点代码,但却我们加深了梯度下降算法和反向传播算法的理解。只要勇敢的迈出这一步后,我们就可以勇敢的尝试它:深度学习中的hello wold–识别...

    上一节我们自己写代码训练了只有一个神经元的反相器,它虽然只有一点点代码,但却让我们加深了梯度下降算法和反向传播算法的理解。只要勇敢的迈出这一步后,我们就可以勇敢的尝试它:深度学习中的hello wold–识别手写数字。

    只有自己写过的代码,才能完全的理解它的用意,不管它多烂,多糟糕,它确是完全属于你的东西。在训练处反相器以后,我开始大胆的尝试自己写一个全连接的神经网络,来训练手写数字。这并不难,也不需要多少代码,我大概花了半天的时间就写完了所有的代码,你也不妨来试试…
    你也可以到这里下载源码:
    mnist-java
    代码结构如下:
    这里写图片描述

    可以看到,我的思路是这样的:
    神经网络(NerualNetwork)由层(Layer)构成,层(Layer)由神经元构成(Nerve)。这种思路非常直观,但它似乎并不是很好的设计,因为代码显得比较繁琐。希望你能设计出更好的结构,或许取消Nerve对象,所有逻辑都放在Layer中更好,这样会大量用到二维数组…

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class DeepLearn3Test {
    	static List<DigitImage> trains = null ;
    	static List<DigitImage> tests = null;
    	public static void main(String[] args) {
    		//load mnist
    		ReadFile rf1=new ReadFile("train-labels.idx1-ubyte","train-images.idx3-ubyte");
    		ReadFile rf2=new ReadFile("t10k-labels.idx1-ubyte","t10k-images.idx3-ubyte");
    		try {
    			tests = rf2.loadDigitImages();
    			trains =rf1.loadDigitImages();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    
    		int size[]={784,40,20,10};
    		NeuralNetwork network = new NeuralNetwork(size);
    		network.radomInitWandB();
    		
    		double image[] = new double[784];
    		
    		for(int kk=0;kk<10;kk++){
    			//first: set input
    			for(int count=0;count<trains.size();count++){
    				for(int i=0;i<784;i++){
    					image[i] = (int)(trains.get(count).imageData[i]&0xff);
    				}
    				network.setInput(image);
    				//second: forward cal output
    				double[] output = network.forwardProc();
    				//third: backward cal delta
    				double[] y = new double[10];
    				for(int i=0;i<y.length;i++){
    					if(i==trains.get(count).label){
    						y[i] = 1;
    					}else{
    						y[i] = 0;
    					}
    				}
    				network.backwarkProc(y);
    				//fouth: update w and b
    				network.updateWAndB(0.5);
    			}
    			System.out.println("finished train count: "+kk);
    		}
    
    
    		
    		
    		boolean isTest = true;
    		//test
    		if(isTest){
    			int countCorrect=0;
    			for(int count=0;count<tests.size();count++){
    				for(int i=0;i<784;i++){
    					image[i] = (int)(tests.get(count).imageData[i]&0xff);
    				}
    				network.setInput(image);
    				//second: forward cal output
    				int number = network.testDigitalImage();
    				if(number==tests.get(count).label)countCorrect++;
    				//System.out.println("count is : "+count+"  number is: "+number+"  label is:  "+tests.get(count).label);
    			}	
    			System.out.println("countCorrect: "+countCorrect);
    		}
    
    	}
    }
    

    代码的思路非常简单:
    1、load mnist
    装在mnist的代码我是从网上找到的,我不知道怎么写,非常感谢牛人的分享。
    2、构建神经网络
    这里构建了一个四层的神经网络

    int size[]={784,40,20,10};
    

    第一层有784个神经元,对应784个像素,中间有两个隐藏层,输出层有10个神经元,对应0~9 共10个数字。

    2、训练
    2-1 设置输入

    network.setInput(image);
    

    2-1 计算输出

    double[] output = network.forwardProc();
    

    2-2 反向传播计算误差

    network.backwarkProc(y);
    

    2-3 跟新权重和偏置

    network.updateWAndB(0.5);
    

    反复重复2中的四步,实现对神经网络的训练。训练完成后,进行测试:
    测试只需要计算输出,然后比对输出是否正确即可。
    这里写图片描述

    经过训练以后,这个神经网络的能正确识别6945个数字,总共是10000个,因此准确率接近70%。对深度学习而言,这并不是值得兴奋的结果,但是,也有值得兴奋的地方。想想,如果不经过训练,我们的神经网络识别的准确率应该是随机的,应该在10%左右,这意味着,我们的神经网络会学习了,虽然它还不够聪明,考试的成绩还不够好,但他似乎已经找到了方向,他变得可以教育了,这让我对他的未来充满期待…


    我最近重写的卷积神经网络CupCnn,在mnist数据集上准确率已经能达到99%了,CupCnn也是用java写的,但是代码更规范,更加模块化,以下是CupCnn在github上的地址,欢迎大家下载:
    CupCnn
    更多详情请参考我的博文:
    java写卷积神经网络—CupCnn简介

    展开全文
  • 使用Tensorflow和MNIST识别自己手写的数字

    万次阅读 多人点赞 2017-03-27 06:17:32
    最近在学习神经网络相关的东西,发现有很多资料是Tensorflow...如何将官方程序变成自己可以利用的程序,网上似乎资料比较少,所以我就来介绍一下如何使用Tensorflow和MNIST搭建自己的手写识别算法,识别自己写的数字。

    使用Tensorflow和MNIST识别自己手写的数字

    最近在学习神经网络相关的东西,发现有很多资料是Tensorflow教程上的内容,但是教程很多只是一个验证官方程序的过程。如何将官方程序变成自己可以利用的程序,网上似乎资料比较少,所以我就来介绍一下如何使用Tensorflow和MNIST搭建自己的手写识别算法,识别自己写的数字(比如下面我写的这个苍劲有力的3~~)。本文也参考了国外大神博客的内容。纯新手,之前在博客上收益良多,也希望能帮助和我一样刚刚起步的童鞋,大家多多指教。
    就来识别这个我写的3吧
    内容如下:
    - Tensorflow和MNIST简介
    - CNN算法
    - 训练程序
    - 写数字,并用Opencv进行预处理
    - 将图片输入网络进行识别


    Tensorflow和MNIST简介

    TensorFlow™ 是一个采用数据流图,用于数值计算的开源软件库。它是一个不严格的“神经网络”库,可以利用它提供的模块搭建大多数类型的神经网络。它可以基于CPU或GPU运行,可以自动使用GPU,无需编写分配程序。主要支持Python编写,但是官方说也有C++使用界面。

    MNIST是一个巨大的手写数字数据集,被广泛应用于机器学习识别领域。MNIST有60000张训练集数据和10000张测试集数据,每一个训练元素都是28*28像素的手写数字图片。作为一个常见的数据集,MNIST经常被用来测试神经网络,也是比较基本的应用。

    CNN算法

    识别算法主要使用的是卷积神经网络算法(CNN)。
    图1.CNN算法结构
    主要结构为:输入-卷积层-池化层-卷积层-池化层-全连接层-输出

    卷积
    卷积其实可以看做是提取特征的过程。如果不使用卷积的话,整个网络的输入量就是整张图片,处理就很困难。
    这里写图片描述
    (这里使用了参考了别人博客中的内容,来源记不清了TAT)
    假设图中绿色5*5矩阵为原图片,黄色的3*3矩阵就是我们的过滤器,即卷积核。将黄色矩阵和绿色矩阵被覆盖的部分进行卷积计算,即每个元素相乘求和,便可得到这一部分的特征值,即图中的卷积特征。
    然后,向右滑动黄色的矩阵,便可继续求下一部分的卷积特征值。而滑动的距离就是步长。

    池化
    池化是用来把卷积结果进行压缩,进一步减少全连接时的连接数。
    这里写图片描述
    池化有两种:
    一种是最大池化,在选中区域中找最大的值作为抽样后的值;
    一种是平均值池化,把选中的区域中的平均值作为抽样后的值。

    实现过程

    1.训练程序

    这里我就先把程序贴出来,主体和tensorflow教程上大致相同。值得注意的是其中的saver部分,将训练的权重和偏置保存下来,在评价程序中可以再次使用。

    from tensorflow.examples.tutorials.mnist import input_data
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
    
    
    import tensorflow as tf
    
    sess = tf.InteractiveSession()
    
    
    x = tf.placeholder(tf.float32, shape=[None, 784])
    y_ = tf.placeholder(tf.float32, shape=[None, 10])
    W = tf.Variable(tf.zeros([784,10]))
    b = tf.Variable(tf.zeros([10]))
    
    
    sess.run(tf.global_variables_initializer())
    
    y = tf.matmul(x,W) + b
    
    cross_entropy = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))
    
    train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
    
    for _ in range(1000):
      batch = mnist.train.next_batch(100)
      train_step.run(feed_dict={x: batch[0], y_: batch[1]})
    correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
    
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    
    print(accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
    
    def weight_variable(shape):
      initial = tf.truncated_normal(shape, stddev=0.1)
      return tf.Variable(initial)
    
    def bias_variable(shape):
      initial = tf.constant(0.1, shape=shape)
      return tf.Variable(initial)
    
    def conv2d(x, W):
      return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
    
    def max_pool_2x2(x):
      return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                            strides=[1, 2, 2, 1], padding='SAME')
    
    W_conv1 = weight_variable([5, 5, 1, 32])
    b_conv1 = bias_variable([32])
    x_image = tf.reshape(x, [-1,28,28,1])
    h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
    h_pool1 = max_pool_2x2(h_conv1)
    
    W_conv2 = weight_variable([5, 5, 32, 64])
    b_conv2 = bias_variable([64])
    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
    h_pool2 = max_pool_2x2(h_conv2)
    
    W_fc1 = weight_variable([7 * 7 * 64, 1024])
    b_fc1 = bias_variable([1024])
    
    h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
    keep_prob = tf.placeholder(tf.float32)
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
    W_fc2 = weight_variable([1024, 10])
    b_fc2 = bias_variable([10])
    
    y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
    cross_entropy = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
    correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    
    saver = tf.train.Saver()  # defaults to saving all variables
    
    sess.run(tf.global_variables_initializer())
    for i in range(20000):
      batch = mnist.train.next_batch(50)
      if i%100 == 0:
        train_accuracy = accuracy.eval(feed_dict={
            x:batch[0], y_: batch[1], keep_prob: 1.0})
        print("step %d, training accuracy %g"%(i, train_accuracy))
    
      train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})
    saver.save(sess, '/home/XXX/learning_tensorflow/form/model.ckpt')  #保存模型参数,注意把这里改为自己的路径
    
    print("test accuracy %g"%accuracy.eval(feed_dict={
        x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

    2.写数字,并用Opencv进行预处理

    训练好了网络,下一步就要测试它了。自己写一个数字,然后用Opencv预处理一下再扔到评价程序里,看看能不能准确识别。
    我们先来识别这张我开头写的3吧:(可以写得再奇怪一些,检测一下识别能力)
    我写的3
    下面我们就要对它进行预处理,缩小它的大小为28*28像素,并转变为灰度图,进行二值化处理。我使用的是Opencv对图像进行处理,也可以使用MATLAB等进行预处理。
    图片预处理程序如下:(程序改编自http://blog.csdn.net/skeeee/article/details/16844937,可以使用鼠标拖动选取框,对选取框中的图像进行处理)

    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <stdio.h>
    
    using namespace cv;
    using namespace std;
    
    cv::Mat org,dst,img,tmp;
    void on_mouse(int event,int x,int y,int flags,void *ustc)//event鼠标事件代号,x,y鼠标坐标,flags拖拽和键盘操作的代号
    {
        static Point pre_pt = cv::Point(-1,-1);//初始坐标
        static Point cur_pt = cv::Point(-1,-1);//实时坐标
        char temp[16];
        if (event == CV_EVENT_LBUTTONDOWN)//左键按下,读取初始坐标,并在图像上该点处划圆
        {
            org.copyTo(img);//将原始图片复制到img中
            sprintf(temp,"(%d,%d)",x,y);
            pre_pt = Point(x,y);
            putText(img,temp,pre_pt,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,0,0,255),1,8);//在窗口上显示坐标
            circle(img,pre_pt,2,Scalar(255,0,0,0),CV_FILLED,CV_AA,0);//划圆
            imshow("img",img);
        }
        else if (event == CV_EVENT_MOUSEMOVE && !(flags & CV_EVENT_FLAG_LBUTTON))//左键没有按下的情况下鼠标移动的处理函数
        {
            img.copyTo(tmp);//将img复制到临时图像tmp上,用于显示实时坐标
            sprintf(temp,"(%d,%d)",x,y);
            cur_pt = Point(x,y);
            putText(tmp,temp,cur_pt,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,0,0,255));//只是实时显示鼠标移动的坐标
            imshow("img",tmp);
        }
        else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))//左键按下时,鼠标移动,则在图像上划矩形
        {
            img.copyTo(tmp);
            sprintf(temp,"(%d,%d)",x,y);
            cur_pt = Point(x,y);
            putText(tmp,temp,cur_pt,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,0,0,255));
            rectangle(tmp,pre_pt,cur_pt,Scalar(0,255,0,0),1,8,0);//在临时图像上实时显示鼠标拖动时形成的矩形
            imshow("img",tmp);
        }
        else if (event == CV_EVENT_LBUTTONUP)//左键松开,将在图像上划矩形
        {
            org.copyTo(img);
            sprintf(temp,"(%d,%d)",x,y);
            cur_pt = Point(x,y);
            putText(img,temp,cur_pt,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,0,0,255));
            circle(img,pre_pt,2,Scalar(255,0,0,0),CV_FILLED,CV_AA,0);
            rectangle(img,pre_pt,cur_pt,Scalar(0,255,0,0),1,8,0);//根据初始点和结束点,将矩形画到img上
            imshow("img",img);
            img.copyTo(tmp);
            //截取矩形包围的图像,并保存到dst中
            int width = abs(pre_pt.x - cur_pt.x);
            int height = abs(pre_pt.y - cur_pt.y);
            if (width == 0 || height == 0)
            {
                printf("width == 0 || height == 0");
                return;
            }
            dst = org(Rect(min(cur_pt.x,pre_pt.x),min(cur_pt.y,pre_pt.y),width,height));
            cv::resize(dst,dst,Size(28,28));
            cvtColor( dst, dst, CV_BGR2GRAY );
            threshold(dst, dst, 170, 255, CV_THRESH_BINARY);
            imwrite("/media/sda/Ubuntu 14.0/myMNIST/MNIST_recognize/temp3.png",dst);//注意将这里改为自己的处理结果存储地址
            namedWindow("dst");
            imshow("dst",dst);
            waitKey(0);
        }
    }
    int main()
    {
        org = imread("/media/sda/Ubuntu 14.0/myMNIST/MNIST_recognize/num3.jpg");//读取图片地址
        org.copyTo(img);
        org.copyTo(tmp);
        namedWindow("img");//定义一个img窗口
        setMouseCallback("img",on_mouse,0);//调用回调函数
        imshow("img",img);
        cv::waitKey(0);
    }

    完成预处理程序后,我们得到了这样的图片:
    处理后图片
    这就是28*28的二值化后的图片,这样的格式和我们MNIST数据集中的图片格式相同。只有这样,我们才能将图片输入到网络中进行识别。

    3.将图片输入网络进行识别

    这里我是编写了一个前向传播的程序,最后softmax层分类的结果就是最后的识别结果啦。
    程序如下:(这里参考了一个外网的博客,地址不记得了。。。)

    from PIL import Image, ImageFilter
    import tensorflow as tf
    import matplotlib.pyplot as plt
    import cv2
    
    def imageprepare():
        """
        This function returns the pixel values.
        The imput is a png file location.
        """
        file_name='/home/mzm/MNIST_recognize/p_num2.png'#导入自己的图片地址
        #in terminal 'mogrify -format png *.jpg' convert jpg to png
        im = Image.open(file_name).convert('L')
    
    
        im.save("/home/mzm/MNIST_recognize/sample.png")
        plt.imshow(im)
        plt.show()
        tv = list(im.getdata()) #get pixel values
    
        #normalize pixels to 0 and 1. 0 is pure white, 1 is pure black.
        tva = [ (255-x)*1.0/255.0 for x in tv] 
        #print(tva)
        return tva
    
    
    
        """
        This function returns the predicted integer.
        The imput is the pixel values from the imageprepare() function.
        """
    
        # Define the model (same as when creating the model file)
    result=imageprepare()
    x = tf.placeholder(tf.float32, [None, 784])
    W = tf.Variable(tf.zeros([784, 10]))
    b = tf.Variable(tf.zeros([10]))
    
    def weight_variable(shape):
      initial = tf.truncated_normal(shape, stddev=0.1)
      return tf.Variable(initial)
    
    def bias_variable(shape):
      initial = tf.constant(0.1, shape=shape)
      return tf.Variable(initial)
    
    def conv2d(x, W):
      return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
    
    def max_pool_2x2(x):
      return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')   
    
    W_conv1 = weight_variable([5, 5, 1, 32])
    b_conv1 = bias_variable([32])
    
    x_image = tf.reshape(x, [-1,28,28,1])
    h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
    h_pool1 = max_pool_2x2(h_conv1)
    
    W_conv2 = weight_variable([5, 5, 32, 64])
    b_conv2 = bias_variable([64])
    
    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
    h_pool2 = max_pool_2x2(h_conv2)
    
    W_fc1 = weight_variable([7 * 7 * 64, 1024])
    b_fc1 = bias_variable([1024])
    
    h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
    
    keep_prob = tf.placeholder(tf.float32)
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
    
    W_fc2 = weight_variable([1024, 10])
    b_fc2 = bias_variable([10])
    
    y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
    
    init_op = tf.initialize_all_variables()
    
    
    
    """
    Load the model2.ckpt file
    file is stored in the same directory as this python script is started
    Use the model to predict the integer. Integer is returend as list.
    
    Based on the documentatoin at
    https://www.tensorflow.org/versions/master/how_tos/variables/index.html
    """
    saver = tf.train.Saver()
    with tf.Session() as sess:
        sess.run(init_op)
        saver.restore(sess, "/home/mzm/MNIST_recognize/form/model2.ckpt")#这里使用了之前保存的模型参数
        #print ("Model restored.")
    
        prediction=tf.argmax(y_conv,1)
        predint=prediction.eval(feed_dict={x: [result],keep_prob: 1.0}, session=sess)
        print(h_conv2)
    
        print('recognize result:')
        print(predint[0])

    通过这个程序,得到最后的识别结果截图如下:
    识别结果
    可以看到识别的结果为3。(花费时间包括了我关闭图像的时间,不是识别的时间。真正的识别时间和计算机的配置有关,使用GPU的话,会小于0.5秒。)
    大功告成!

    整个识别自己手写数字的过程就是这样,参考了很多大神编写的程序,在自己编写的过程中还是学到了不少。博客是过了一段时间写的,预处理程序重新写了一下,如有错误,还请多多指教啊。

    展开全文
  • 杂谈_怎样写好英语

    千次阅读 2012-12-29 17:43:03
    但是就有人字写得奇烂,写完了连自己都不认识!不过你也别着急,英语书法是比较练的,要写一手漂亮的字,只需要十分钟即可,立竿见影。许多经我指点的学生,第二天交作业后,遭到老师的叱责,说他是找别人代写的...

    奉上一张英语连写规则,速杆见影阿,





    书法是门面,谁都想写一手好字来装点门面。但是就有人字写得奇烂,写完了连自己都不认识!不过你也别着急,英语书法是比较好练的,要写一手漂亮的字,只需要十分钟即可,立竿见影。许多经我指点的学生,第二天交作业后,遭到老师的叱责,说他是找别人代写的作业。

    下面是英语书法中要做到或注意的一些事项:

    1、大写字母写在第一格和第三格内,上面不要顶格,要留有一点儿余地,下面要压齐第三条线,其书写方法同印刷体的书写法基本一样,毋庸赘述;

    2、小写字母手写体和印刷体是不完全一样的,要特别注意f g k y的手写体和印刷体之间的区别;

    3、不要把下列字母互相写混:d和cl ol el、r和v、a和u、c和e等;

    4、写下列字母a c e m n o r s u v w x z时,要灌满中间格,注意要灌满,不要写大,更不要写小;

    5、写b d h k时,上面要顶格,下面压齐第三格,中间的“圈儿”的上面不要高于第二格,也不要低于这个格;

    6、写g p q y时,下面要压齐第四格,上面要顶第二格;

    7、i的主体在二三格之内,要灌满二三格,点儿点在一二格内靠下的位置,点圆;

    8、j的主体在二四格之内,上下顶格,点儿点在一二格靠下的位置,点圆;

    9、t上面不要顶格,顶部写到一二格中间的位置即可,下面压齐第三格,横线要写在第二格的横线上,要写平;

    10、f是英文字母中唯一四个格全占的字母,写在四个格之内的,上下顶格,横线要写在第二格的横线上,要写平要特别注意它和印刷体区别巨大;

    11、在写单词时,i j的点儿,f t的横线以及x的左撇要在写完一个单词的整体部分后再按反方向写上;

    12、写的时候,该对齐的地方一定要对齐,有格的时候要写齐,没格的时候也要写齐;

    13、在一个单词内所有的字母都可以连写,这样看起来每个单词都是手拉手的整体。但是,连笔写的时候要有个原则,就是清晰不混。字母的非主体部分,要以重复走过的笔迹为主,不能重复的时候才能带点儿痕迹,严防重复时画圈,特别是在可能引起误会的情况下更不能画圈;

    14、单词内部字母可以连写,但绝对禁止粘在一起从而使读者无法区分是哪个字母;

    15、切忌写单词的时候读出字母名称,应该读出字母或字母组合在该单词中的读音,字母在字母表中的名称音和在单词中的读音常常是不一样的;

    16、切记,该写的时候写,不该写的时候不要写,要写就写好;

    17、要想写好英语书法的最关键要做的一件事情就是:拒绝老师留的抄写作业!够叛逆的吧?你敢吗?可是你一定要记住,常常要你抄写单词的和罚你抄写的绝对不是好老师,这比体罚更严重,会害得你终生学不好英语,进而贻误你一生的前程!不过话说回来了,你拒绝不了那抄写作业,怎么办呢,我告诉你,要想有成效,你就得抱着积极的态度去完成它:把每个单词都读准后再默写下来。这可能更费时间,但是能达到熟练和记住单词的效果;

    18、最后我要郑重提出的是,不要用抄写的办法去记单词,用抄写的方法背单词,实际是在背字母的写法,学到老你也走不出英文字母表,且越写越乱,写了也不会读,这远远地背离了应该让学生认识到英语是一种拼音文字的因材施教的原则(这里我说的“材”是教材)。英语单词不像汉字那样,不会的写的,写写就会了,如果你用写汉字的办法去写英语单词,就注定了你永远都学不好英语!

    19、最后的最后,我要奉劝那些把板书写得让学生认不清的英语老师(其实你自己也认不清,不信你写完了下来看看,你自己还认识吗?)花点儿时间练练书法吧,先别说是为了孩子们的前途,就算是为你自己的脸面,也是必要的。



    展开全文
  • 【小白】如何写好自己的一篇CSDN博客(美化1)

    万次阅读 多人点赞 2018-11-30 19:34:42
    (下面是我个人完几篇blog的心得,你拥有炫酷博客~) 目录(一) 创建自己第一篇文章(二)个人主页美化 (一) 创建自己第一篇文章 登录CSDN,找到它,点击开始你的第一篇博客。 CSDN主要有两种...

    前提:你得拥有一个CSDN账号!
    (下面是我个人写完几篇blog的心得,让你拥有炫酷博客~)
    在这里插入图片描述

    (一) 创建自己第一篇文章

    1. 登录CSDN,找到它11,点击开始写你的第一篇博客。

    2. CSDN主要有两种编辑器:Markdown编辑器和富文本编辑器;我选的环境:Markdown编辑器。
      在这里插入图片描述

      Markdown编辑器特点

      • 左右对比查看,方便修改;
      • 最上面一栏和我们常用的office/WPS用法相同;
      • 编辑器支持常用快捷键:ctrl+c(复制)、ctrl+v(粘贴)、ctrl+z(撤销最后一次编辑)等;具体用法可打开保存旁边的问号按钮——帮助文档;
      • 支持强力拖拽来粘贴图片,将Word上的图片直接拖拽到Mark文档上;当然最上面一栏引入图片也可以从电脑文件夹中上传一张图片;我个人喜欢用快捷键粘贴图片~
      • 记得常点击保存,避免断电、断网、意外关闭网页造成心血化为泡沫;
      • 最后点击发布文章,好的标签、分类也是一片好文章所必要的。

      当然,并不是发布后就无法挽回,进入CSDN文章管理页面,随时可以再次对其进行编辑完善~

    3. 题目位置:在最上端哦;拥有一个炫酷的title你已经成功了一大半了。
      在这里插入图片描述

    4. 导航目录:这是Markdown编辑器为博主提供的目录导航快捷方式,方便读者阅读时直接跳转到相应目录,很人性化的设计哦,具体实现如下:
      在这里插入图片描述
      在文章编辑时我们通常会设置一级标题(“#”+“一个空格”)、二级标题(“##”+“一个空格”)、三级标题(“###”+“一个空格”)等,在Markdown编辑器下提供了6级标题:
      在这里插入图片描述
      如何体现的呢:
      当你设置了一级标题时,如下:
      在这里插入图片描述
      设置二级标题和更低级标题时,“好导航、不迷路”:
      在这里插入图片描述

    5. 文本样式:可以使用菜单栏的快捷方式,也可以手敲命令实现彩色文案,效果比全篇黑白文案好很多哦!
      在这里插入图片描述

    字体背景色:
    在这里插入图片描述

     <table><tr><td bgcolor=orange> 背景色是orange</td></tr></table>
    

    字体美化:
    在这里插入图片描述

    <font color="red">中间写上想说的话</font>
    <font color=#f111f1>中间写上想说的话</font>
    
    <font face="黑体">黑体字示例</font>
    <font face="微软雅黑">微软雅黑示例</font>
    <font face="STCAIYUN">华文彩云示例</font>
    
    <font color=#0099ff size=5 face="STCAIYUN">color=#0099ff size=6 face="黑体"</font>
    <font color=red size=5>color=#00ffff</font>
    

    安利其他博主的总结:

    1. 颜色库
    2. 搭配实例 ~~ 干货建议收藏 !!

    分享一下我个人常用的16进制颜色图
    在这里插入图片描述
    6. 插入代码、图片、动图:
    插入代码片:这是程序猿交流、分享经验不可或缺的一步,下面是几段代码片的实践,大家来感受一下:
    在这里插入图片描述

    插入代码片时,记得输入相应的语言种类才能高亮哦!

    1. 插入图片:
      插入图片方法:

      a. 用快捷键粘贴图片、文字等:
      ctrl+c(复制)、ctrl+v(粘贴),可以从Word上粘贴到Markdown编辑器上,不用每次点击另存Word图片再上传了,人性化+1;
      b.暴力插入:
      强力拖拽来粘贴图片,将Word上的图片直接拖拽到Mark文档上;但是Markdown编辑器不支持文字拖拽排序,只能选中文本Ctrl+z和Ctrl+v来调整编辑器上文字、图片、代码片的顺序;
      c. 菜单栏引入:
      图片也可以从电脑文件夹中上传一张图片,最原始,通常引入文件夹中的图片、视频等。

      改变图片大小:
      原图:直接复制过来,不做改变
      按原图比例缩放:在70后面+“一个空格”+“=尺寸”+“小写的x”
      按固定大小缩放:在70后面+“一个空格”+“=长x高”原图:![在这

    2. 插入GIF动图:

    • 从文件夹上传GIF动图
      在这里插入图片描述
    • 手机录屏.mp4在线转GIF上传
      (1). 任意下载一个手机录屏软件–例如:录屏精灵
      (2). 录制完之后是一个mp4格式的视频文件,上传到电脑,
      (3). 将其转成gif动态图请打开在线转换器https://ezgif.com/video-to-gif
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      如果你觉得满意就Save到本地吧,最后上传到CSDN上就可以啦~
      示例:
      在这里插入图片描述
    1. 优化排版

      有没有遇到排版前后层次不齐呢,解决方法——空格拯救强迫症星人!

      下面的示例大家感受一下:
      问题一:标题上的中英文括号不一致,空格个数不一致,#个数不一致
      在这里插入图片描述
      问题二:插入片段、图片、代码片没有层次感
      在这里插入图片描述
      问题三:图片位置乱窜
      在这里插入图片描述
      问题四:不仅是图片,文字内容未换行,排版效果都会差很多,在你写博客的时候也会有明显感受!要注意换行哦!

      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

      问题五:序号排列不整齐:注意在“1. ”后有一个空格,与标题“# ”后有一个空格同理:
      在这里插入图片描述

    2. 再次强调注意保存保存!!!

    3. CSDN还有一个设置我要透露一下,不建议在非工作时间发博哦!就算你发了,也处于在审核状态,读者无法阅读;等待审核不如第二天9:00后再发一次,因此,习惯深夜码字的猿们非常不解,这算是CSDN的一个弊端吧!
      在这里插入图片描述

    (二)个人主页美化

    一个漂亮的博客不仅得有可读性高的博文,CSDN支持个人主页设置~

    • 进入文章管理
      在这里插入图片描述
    • 进入博客设置:设置博客标题、描述、皮肤、默认编辑器、代码片样式、版权声明~
      在这里插入图片描述
      在这里插入图片描述

    最后,再炫酷的博客都不如优秀的内容支撑,技术贴才是好的贴~

    展开全文
  • 一手好字:硬笔书法轻松自学指南(知乎周刊 Plus) 知乎编辑团队 楷书,认知好字的范本 2017-03-16 《黄自元间架结构九十二法》 选本字帖 2017-03-16 先谈书体。 前人对练习书法的程序,各有主张。有的认为...
  • 给学弟学妹们了个 15W 的图解操作系统!

    万次阅读 多人点赞 2021-05-11 09:04:11
    不知不觉在 CSDN 里了 23 篇图解操作系统的系列文章,总字数高达 15W ,而且每篇都配了很多自己手绘的图,也算有个体系了。 然后图解操作系统文章也帮助到了很多读者,时不时都会有读者给小林发感谢信,说我的...
  • 最合适代码的字体

    千次阅读 2015-01-27 15:05:12
    每天盯着屏幕代码,自然需要寻找一种看得舒服的字体,能让自己的代码赏心悦目,一般来说,我们选择用于显示代码的字体,有如下几个要求: 字母的宽度一致 或称为等宽字体,由于代码文件是普通文本,不带...
  • 别人的代码看起来容易,自己写未必 古人云说起来容易,做起来难。就像我们看小说一样,我们看完小说都看得懂,里面的人物事件都搞得清清楚楚,可这不代表我们能得出来。对于我们这些码农来说,有些...
  • 第一:写好网页: 1.首先你要编写好网页,最简单的就是用div+css写一个静态的html文件,如:index.html。 第二:购买服务器和域名,用于存放你的网页 1.购买一台服务器,建议去阿里云的centos服务器。 服务器:为什么...
  • 网站原创文章怎么写才能收录?站长们都知道,文章对SEO的重要性,一篇高质量的原创文章要胜过N篇采集来的文章。那么,我们应该如何根据用户需求出用户需要的文章呢?下面,曾庆平SEO就为大家讲一下如何出既符合...
  • 在前面 本文所讲的代币是使用以太坊智能合约创建,阅读本文前,你应该对以太坊、智能合约有所了解,如果你还不了解,建议你先看以太坊是什么 代币Token 如果不那么追求精确的定义,代币就是数字货币,比特币...
  • 究竟怎样代码才算是代码

    万次阅读 多人点赞 2016-09-21 16:05:06
    今天我们来谈谈代码吧。代码重要吗?当然,代码就是设计(Jack W.Reeves, 1992);代码是最有价值的交付物。我们需要代码吗?在给“代码”下个定义之前,这个问题无法回答。那么,究竟什么是代码?看下面这...
  • 2.写好一封工作邮件,重要的不是“怎么写”,而是“什么该写,什么不该写”。 3.重要的备忘、通知和需要留底的话,最好通过工作邮件传递。 I、如何做到位极人臣?(奏章和来往批复的文件写得好) 回到古代,司马光跟...
  • 谈一下自己写论文的经验

    千次阅读 2013-05-23 16:06:41
    谈一下自己写论文的经验  在学校读书的9年里面,直到最后1年才开始练习写文章,所以自己写文章的水平肯定是不高的。...然后写一点自己认为如何能把文章写好应该注意的方面。不过归根结底都是需要不断练习,长期积累才
  • 自己写操作系统学习总结

    万次阅读 多人点赞 2017-05-04 23:26:21
    怎样自己写一个简单的操作系统? https://www.zhihu.com/question/20207347 我的时候一些经历: 第一次的时候3000行左右的就无法调试了,当时主要参考了linux 0.11(基础太潜)。 第二次的时候,基本定下...
  • 如何才能使自己看懂英文文献

    千次阅读 2016-01-16 14:59:42
    来自知乎:... --------------------------------------------------------------------------------------------------- ...“如何才能使自己看懂英文文献”,其实在这里“看懂
  • 代码规范、如何代码

    万次阅读 2016-08-08 15:41:14
    代码规范、如何代码 上大学以来,每当看到的文章,第一反应都是使用浏览器的收藏功能,收藏下来,久而久之,收藏的网址越来越多。虽然浏览器收藏夹也有文件夹的功能可以分门别类,但是终究没有博客的Tag...
  • 如何写好一份PPT?

    千次阅读 2018-10-17 13:57:14
    我们在日常工作中经常能够看到像下面图片这样丑到爆炸的PPT,...不是他们不用心,而是他们真的不知道怎么才能把PPT做好看。 其实在三顿看来,PPT是由配图、配色、字体、排版这些内容组成。如果能把这四块内容的一...
  • 《IDA Pro代码破解揭秘》 《IDA Pro权威指南(第2版)》 在最后 如果你想进大厂,想升职加薪,或者对自己现有的工作比较迷茫,都可以私信我交流,希望我的一些经历能够帮助到大家~~ 推荐阅读: 《全网最全性能...
  • 写好一份数据分析报告需要注意的13个要点先说说写一份好的数据分析报告的重要性,很简单,因为分析报告的输出是是你整个分析过程的成果,是评定一个产品、一个运营事件的定性结论,很可能是产品决策的参考依据,既然...
  • 程序员该如何去写自己的简历-代码而成的简历

    万次阅读 多人点赞 2013-10-21 13:11:17
    首先,声明这是给程序员看的,而不是码农。其次,如果你不幸是码农那么请成为程序员。最后,码农和程序员是有区别的,程序员应该是有思想的手工艺人,在这个机械高度生产化的世界里,人口众多的手工行业就是程序员...
  • 点击关注上方“五分钟学算法”,设为“置顶或星标”,第一时间送达干货。博客大致可以分为三步:写作前写作中写作后按照这三步介绍这个过程中我用到一些工具。写作前trello官网地址:http...
  • 怎样写好求职简历(STAR法则)

    万次阅读 2016-07-27 18:28:11
    简历该如何才能有更多的面试机会?  其实我在看你们简历的时候就想知道以下内容:你是否能胜任这份工作?是否有上进心?是否够积极主动?是否有潜力?就这几项,如果你做不到这么多,起码得保证自己简单点,...
  • Unity游戏制作,本篇文章介绍了复刻皇室战争玩法的一个自制小游戏,共有该游戏的两万教程加制作过程,欢迎品尝! 世界上没有绝对的公平,如果我们起点就比别人第一步,那就更需要比别人努力了。
  • 如何写好一份前端简历

    千次阅读 多人点赞 2019-02-17 23:52:26
    简历不是一份记流水账的东西,而是用人方了解你的亮点。 要应付并通过面试并不难,但是,千万不要应付你的人生,你学技术不是用来面试的,它至少来说是你谋生的技能,要尊重自己的谋生技能,说不定,哪天你还要用...
  • 花了小半小时,测完竟然我交钱才能看结果??我。。。只好交了19.9元,测出来132,感觉被割韭菜了,这谁测出来是不是都挺高?! 于是我打算自己手写一版,大家不用交钱也能测! 问卷准备 当然我不打算自己写一个...
  • 每个程序员都应该给自己写本书

    千次阅读 多人点赞 2013-07-10 06:38:01
    因为看的书相对比较多,最近又了一本,感觉多少有点发言权,因此把自己的经过和感受出来,供想书的做些参考。现在浮躁的人比较多,所以我先说书不能达成什么目标。最关键的一点是程序员书基本不能你发财...
  • 写好软件的75条

    千次阅读 热门讨论 2006-04-25 11:20:00
    写好软件的75条 1. 你们的项目组使用源代码管理工具了么?应该用。VSS、CVS、PVCS、ClearCase、CCC/Harvest、FireFly都可以。我的选择是VSS。
  • 如何写好一篇技术文章?

    千次阅读 2017-10-27 00:00:00
    文章整理自: 掘金YoungZ 、Github ruanyf、知乎 敖天羽 很多开发者都喜欢在各类社区平台分享一些写作内容,一方面可以对人生的一些经历进行记录...但更多的开发者会问,文章到底怎么?什么的样的文章可以得到

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 425,375
精华内容 170,150
关键字:

怎么才能让自己字写好