페이지

2018년 2월 11일 일요일

Chapter 2. Setting up a Laravel Development Environment

- Composer
Composer is a dependency manager for PHP, much like NPM for Node or RubyGems for Ruby. You'll need Composer to install Laravel, update Laravel, and bring in external dependencies.

- Local Development Environments

However, Laravel offers two tools for local development, Valet and Homestead, and  we'll cover both briefly. If you're unsure of which to use, I'd recommend useing Valet and just skimming the Homested section; however, both tools are valuable and worth understanding.

- Laravel Valet
If you want to use PHP's build-in web server, your simplest option in to serve every site from a localhost URL. If your urn php -S localhost:8000 -t kpublic from yhour Laravel site's root folder, PHP's built-in web server your site a http://localhost:8000/. You can also run php artisan serve once you have your application setup to easily spin up an equivalent server

But if yhou're interrested in tying each of your sites to a specific development domain, you'll need to get comfortabel with your operationg system's host file and use a tool like dnsmasq. Let's instead tyr something simpler.

If your're a Mac user (there are also unofficial forks for Windows and Linux), Laravel Valet takes away the need to connnect  yhour domains to your applicaiton folders. Valet install dnsmasq and a series of PHP scripts that make it possible to tyhpe laravel new myapp && open myapp.dev and for it to just work. You'll need to install a few tools using Homebrew, which thedocumentaion will walk you through, but the steps from initial installation to serving your apps are few and simple.

Imstall Valet (see the docs for the latest installation instruction- it's under very active developoment at this time of writing), and point it at one or more directories whrere your sites will live. I ran valet park from my ~/Sites directory, which is where I put all of my under-development apps. Now, you can just add .dev to the end of the directory name and visit it in your browser.

Valet makes it easy to serve all folders in a given folder a "FOLDERNAME.dev" using valet park, to server just a single folder using valet link, to open the Valetserved domain for qa folder using valet open, to serve the Valet site with HTTPS using valet secure, and to open an ngrok tunnel so you can share your site with others with valet share.

- Laravel Homestead
Homestead is another tool you might want to use to set up your local developement environment. It't configuration tool that site on top of Vagrant and providers a preconfigured virtual machine image that i perfectly set up for Laravel developemnt, and mirrors the most common production environment that many Laravel sites run on.

Setting up Homestead

If your choose to use Homestead, it's going to take a bit more work to set up than something like MAMP or Valet. The benefits are myriad, however: configured correctly,  your local environment can be incredibly close to your ermote working environmnent; you won't have to worry about updating yuour dependencies on your local machine; and you can learn all about the structure of Ubuntu servers from the safety of your local machine.

What tools do Homestread Offer?
Your can always upgrad the individual components of your Homestread virtual machine, but here are a few inmportant tools Homestgead comes with by default:
- To run the server and serve the site, Ubuntu, PHP, and Nginx (a web server similar to Apache).
- For database/storage and queues, MySQL, Postgres, Redis, Memcached, and beanstalkd.
- For build steps and other tools, Node.

Installing Homesterad''s dependencies
First, you'll need to deonload and install either VirtualBox or VMWare, VirturalBox is most common because it's free.

Next, download and install Vagrant.

vagrant is convenient because it makes it easy for your to rectre a new local virtual machine from a precreated "box", which is essentially a tmeplate for a virtual machine. So, the next step is to run vagrant box andd laravel/homestread from your terminal to download the box.

Installing Homestead

Next, let's actually install Homeestead. You can install multiple instances of Homestead(perhaps hosting a different Homestread box per project), but I perfer a single Homestread virtual machine for all of my projects. It you wnat on per project, you'll want to installl Homestead in your project directory; check the Homestread documentation online for instructions. If you want a single virtual machine for all of your projects, instlal Homesterad in your user's home directory useing the following command:

git clone https://github.com/laravel/homestead.git ~/Homestead

Now, run the initialization script from wherevent you put the Homestead directory:

bash ~/Homestead/init/sh
This will place Homestead's primary configuration file, Homestead.yaml, in a new ~/.homestead directory.

Configuring Homestead
Open up Homestead.yaml and configure it how yhou'd like. Here's what it looks like out of the box:
ip : "192.168.10.10"
memory: 2048
cpus: 1
oorivuder: virtualbox

authorize: ~/.ssh/id_rsa.pub

keys:
   - ~/.ssh/id_rsa

folders:
   - map: hoestead.app
      to: /home/vagrant/Code

sites:
   - map: homestead.app
      to:/home/vagrant/Code/Laravel/public

databases:
     - homestead

# blackfire:
#      - id: foo
#        token: bar
#        client-id: foo
#        client-token: bar


# ports:
#         - send: 5000
#           to : 5000
#          - send: 7777
#           to : 7777
#           protocol: udp

You'll need to tell it your provider( likely virtualbox), point it to yhour public SSH key(by default ~/.ssh/id_rsa.pub; if you don't have one, GitHub has a gread tutorial on creating SSH keys), map folders and sites to their local machine equivalents, and provison a database.

Mapping folers in Homestead allows you to edit files on your local machine and have those files show up in your Vagrant box so they cna be serverd. For example, it you rhave a ~/Sites directory whrere your put all of your code, your'd map the folders in Homeestead by replacing the folders section in Homestead.yaml with the floowing:

folders:
   - map: ~/Sites
       to: /home/vagrant/Sites

You've now just created a directory in your Homestead virtual machine at /home/vagrant/Sites that will mirror your computer's directory at ~/Sites.

Top-level domains for development sites
You cna chooese nay converntion for local development sites' URLs, but .app and .dev are the most common. Homesteread suggest. .app, so if I'm working on a local copy of symposiumapp.com, I'll develop at symposiumapp.app.
Technically, .app and .dev are valid TLDs, so by choosing them for your won internal use, you could be confliciting with real domains.
This doesn't really bother me, but if you're concerned, there are four TLDs reserved for development purposes: .example, .test, .invlid, and .localhost.

Now, let's setup our first example website. Let's say our live site is going to be projectName.com. In Homestead,yaml, we'll map our local development folder to projectName.app, so we have a separate URL to visit for local development:


sites:
       -map: projectName.app
         to: /home/vagrant/Sites/projectName/public

As you can see, we're mapping the URL projectName.app to the virtual machine directory /home/vagrant/Sites/projectName/public, which is the public folder within our Laravel install. We'll learn more about that later.

Finlly, you're going to need to teach your local machine that, when you try to visit proejctName.app, it should look at your computer's local IP address to resolve it Mac and Linux users should edit /etc/hosts, and Windows users C:\Windows\System32\direvers\etc]host. Add a line to this file that looks lick this:

192. 186.10.10 projectName.app

Once you've provisioned Homeestead, your site will be available to browse (on your machine) at http:.//projectName.app/.

Creating databases in Homestead
Just like you can define a site in Homestead.yaml, you can slso define a database. Databases are a lot simpler, because  you're only telling the provisioner to create a database with that name, nothing else. We dothis a follows:

databases:
     -projectname

Provisioning Homestead
The first time your acually turn on a Homestead box, you need to tell Vagrant to initialize it. Navigate to your Homestead directory and run vagrant up:

cd ~/Homestead
bagrant up

Your Homestead box is now up and running: it's mirroring a local folder, and it's serving it to a URL you can visit in any browser on your computer. It also has created a MySQL database. Now that your have that environment running, you're ready to test up your first Laravel project - but first, a quick note about using Homestead day-to-day.

Using Homestead day-to-day

It's common to leave your Homestead virtual machine up and running at all times, but if you don't, or if you have recently restarted your computer, you'll need to know how to spin the box up and down.

Since Homestead is based on Vagrant commands, you'll ust use basic Vagrant commands for most Homestead actions. Change to the directory where you installed Homestead (using cd) and then run the following commands as needed:

- vagrant up spins up the Homestead box.
- vagrant suspend takes a snapshot of where the box is and tehn shuts it down;
like "hibernating" a desktop machine.
- vagrant halt shuts the entire box down; like turning off a desktop machine.
- vagrant destory deletes the entire box; like formatting a desktop machine.
- vagrant provision re-runs the provisioners on the preexisting box.

Connecting to Homestead databses from desktop applications
If yhou use a dsktop application like Sequel Pro, you'll likely want to connect to your Homestead MySQL databases from your host machine. These settings will get you going:

- Connection type: Standard(non-SSH)
- Host: 127.0.0.1
- Username:homestead
- Password:secret
- Post:33060

Creating a New Laravel Proejct
There are two ways to create a new Laravel proejct, but both are run from the command line. The first option is to globallyinstlal the Laravel installer tool( using Composer); the second is to use Composer's create-project feature.
You can learn about both options in more detail on the Installation documentation page, but I'd recommend the Laravel installer tool.

Installing Laravel with the Laravel Installer Tool
If you have Composer installed globally, installing the Laravel installer tool is as simple as running the following command:

composer global require "laravel/installer=~1.1"
Once you have the Laravel installer tool installed, spinning up a new Laravel proejct is simple. Just run this command from yhour command line:

laravel new proejctName

This will create a new subdirectory of your current directory named projectName and install a bare Laravel project in it.

Installing Laravel with Composer's create-proejct feature
Composer also offers a feature called create-proejct for creating new projects with a particular skeleton.to use this tool to create a new Laravel project, issue the following command:

composer create-proejct laravel/laravel projectName --prefer -dist

Just liek the installer tool, this will crfeate a subdirectory of your current directory named proejctName that contains a skeleton Laravel install. ready for you to develop.

Laravel's Directory Structure
When you openup a direcotry that contains a skeleton Laravel application, you'll see the following files and direcories:

app/
bootstrap/
config/
database/
public/
resources/
routes/
storage/
tests/
vendor/
.env
.ev.example.
.gitattributs/
.gitignore
artisan
composer.json
compoer.lock
gulpfile.js
package.sjon
phpunit.xml
readme.md
server.php

Let's walk through them one by one to get familiar.

The Folders
The root directory contains the follwoing folders by default:
- app is where the bulk of your actual application will go. Models, controllers, route definitions, commands, and yhour PHP domain code all go in here.
- bootstrap contains the files that the Laravel framework uses to boot every time it runs.
- config is whrere all the configuration files live.
- database is where database migrations and seeds live.
- public is the directory the server points to when it's serving the website. This contains index.php, whichis the front controller that kicks off the bootstrapping process and routes all requests appropriately. It's also where any public-facing files like images, stylesheets, scripts, or downloads go.
- reousrce is when non-PHP files that are needed for other scripts live. Views, language files, and (opotionally)Sass/LESS and source JavaScript files live here.
- routes is where all of the route definitions live, both for HTTP routes and "console routes," or Artisan commands.
- storage is where cashes, logs, and compiled system files live.
- tests is where unit and integration tests live.
- vendor is where Composer installs its dependencies. It's Git-ignored(marked to be excluded from your version control system), as Composer is expected to run as a part of your deploy process on any remote servers.

The Loose Files
The root directory also contains the following files:

- .env and .env.example are the files that dictate the environment variables (variables that are expected to be different in each environmnet and are therefore not committed to version control). .env.example is a template that each environment should duplicate to create its own .env file, which is Git-ignored.

-artisan is the file that allows you to run Artisan commands (see Chapter 7) from the command line.
-.gitignore and .gitattributes are Git configuration files.
- composer.json and composer.lock are the configuration files for Composer; composer.json is user-editable and composer.lock is not. These files share some basic information about this proejct and aslo define its PHP dependencies.
-gulpfile.js is the (optional) configuration file for Elixir and Gulp. This is for compiling and processing your frontend assets.
-package.json is like composer.json but for frontend asserts.
-phpuniut.xml is a configuration file for PHPUnit, the tool Laravel users for testing out of the box.
- readme.md is a Markdown file giving a basic introduction to Laravel.
-server.php is a backup server that tries to allow less-capable servers to still perview the Laravel application.

Configuration
The core settings of your Laravel application-database connection, queue and mail settings, etc. - live in files in the config folder. Each of these files returns an array, and each value in the array will be accessible by a config key that is comprised of the filename and all descendant keys, separated by dots(.)

So, if you create a file at config/service.php that looks like this:

// config/services.php
return [
       'sparkost' => [
            'secret' => 'abcdefg'
      ]
 ];

you will now have access to that config variable using config('services.spark post.secret').
Any configuration variables that should b distinct for each environment(and therefore not committed to source control) will instead live in your .env files. Let's say your want to use a different Bugsnag API key for each environment. You'd set the config file to pull it from .env:

  // config/services.php
  return [
       'bugsnag' => [
              'api_key'   => env('BUGSANG_API_KEY')
       ]
 ];

This env() helper function pulls a value from your .env file with tat same key. So now, add that key to your .env (settings for this environment)and .env.example(template for all environmnets) files:
 BUGSNAG_API_KEY=oinfp9813410942
your .env file already contains quite a few environment-specific variables needed by the framework, like which mail driver you'll be suing and what your basic database settings are.

Up and Running

You're now up and running with a bare Laravel install, Run git init, commit the bare files with git add . and git commit, and you're ready to start coding. That's it!
And if you're using Valet, you can run the follwing commands and instantly see your site live in your browser:
laravel new myProejct && cd myProejct && valet open

Every time I start a new project, these are the steops I take:

laravel new  myProejct
cd myProejct
git init
git add .
git commit -m "Inital commit"

I keep all of my sites in a ~/Sites folder, which I hava set up as my primary Valet directory, so in this case I'd instantly have myProejct.dev accessible in mybrowser with no added work. I can edit .evn and point it to particular database, add that database in my MySQL app, and I'm ready to start coding.

Lambo
I perform this set of steps so often that I created a simple global Composer package to do it for me. It's called Lambo, and you can learn more about it on GitHub.

Testing
In every chapter after this, the "Testing" section at tne end of the chapter will show you how to wirte test for the feature of reatures that were coverd. Since this chater doesn't cover a testable feature, let's talk test quickly.(To lean more about wirting and running tests in Laravel, head over to Chapter 12.)


Out of the box, Laravel bring in PHPUnit as dependency and is configured to ren the tests in any file in the tests directory whose name ends with Test.php(for example, tests/UserTest.php).

So, the simplest way to write tests is to create a file in the tests directory with a anme that ends with Test.php. And the easiest way to run them is to run ./vendor/bin/phpunit from the command line (in the proejct root).

If nay tests require database access, be user to run your tests form the machine where your database is hosted- so if you're hosting your databases in Vagrant, make sure to ssh into your Vagrant box to run your test from there. Again, your can learn about this and much more in Chapter 12.


TL;DR
Since Laravel is a PHP framework, it's very simple to serve it locally. Laravel also provides two tools for maanging your local developoment: a simpler tool called Valet that uyses your local machine to provide your dependencies, and a preconfigured Vagrant setup named Homested. Laravel relies on, and can be installed by, Composer, and comes out of the box with a series of folders and files that rreflect both its conventiions and its relationship with other open source tools.








2018년 2월 10일 토요일

CHAPTER1 The Neural Network.

- Building Intelligent Machines
The brain is the most incredible organ in the human body. It dictates the way we perceive every sight, sound, smell, taste, and touch. It enables us to store memories, experience emotions, and even dream. Without it, we would be primitive organisms, incapable of anything other than the simplest of reflexes. The brain is, inherently, what makes us intelligent.

The infant brain only weighs a single pound, but somehow it solves problems that even out biggest, most powerful supercomputers find impossible. Within a matter of months after birth, infants can recognize the faces of their parents, discern discrete objects from their backgrounds, and even tell apart voices. Within a year, they've already developed an intuition for natural physics, can track objects even when they become partially or completely blocked, and can associate sounds with specific meanings. And by early childhood, they have s sophisticated understanding of grammar and thousands of words in their vocabularies.

For decades, we've dreamed of building intelligent machines with brains like ours-robotic assistants to clean our homes, cars that drive themselves, microscopes that automatically detect diseases. But building these artificially intelligent machines requires us to solve some of the most complex computational problems we have ever grappled with; problems that our brains can already solve in a manner of microseconds. To tackle these problems, we'll have to develop a radically different way of programming a computer using techniques largely developed over the past decade. This is an extremely active field of artificial computer intelligence often referred to as deep learning.

- The Limits of Traditional Computer Programs
Why exactly are certain problems so difficult for computers to solve? Well, it turns out that traditional computer programs are designed to be very good at two things: 1) performing arithmetic really fast and 2) explicitly following a list of instructions. So if you want to do some heavy financial number crunching, you're in luck. Traditional computer programs can do the trick. But let's say we want to do something slightly more interesting, like write a program to automatically read someone's handwriting.


Figure 1-1 will serve as a starting point.
Figure 1-1. Image from MNIST handwritten digit dataset

Although every digit in Figure 1-1 is written in a slightly different way, we can easily recognize every digit in the first row as a zero, every digit in the second row as a one, etc. Let's try to write a computer program to crack this task. What rules could we use to tell one digit from another?

Well, we can start simple! For example, we might state that we have a zero if our image only has a single, closed loop. All the examples in Figure 1-1 seem to fit this bill, but this isn't really a sufficient condition. What if someone doesn't perfectly close the loop on their zero? And, as in Figure 1-2, how do you distinguish a messy zero from a six?

Figure 1-2. A zero that's algorithmically difficult to distinguish from a six
You could potentially establish some sort of cutoff for the distance between the starting point of the loop and the ending point, but it's not exactly clear where we should be drawing the line. But this dilemma is only the beginning of our worries. How do we distinguish between threes and fives? Or between fours and nines? We can add more and more rules, or features, through careful observation and months of trial and error, but it's quite clear that this isn't going to be an easy process.

Many other classes of problems fall into this same category: object recognition, speech  comprehension, automated translation, etc. We don't know what program to write because we don't know it's done by our brains. And even if we did know how to do it, the program might be horrendously complicated.

- The Mechanics of Machine Learning
 To tackle these classes of problems, we'll have to use a very different kind of approach. A lot of the things we learn in school growing up have a lot in common with traditional computer programs. We learn how to multiple numbers, solve equations, and take derivatives by internalizing a set of instructions. But the things we learn at an extremely early age, the things we find most natural, are learned by example, not by formula.

For instance, when we were two years old, our parents didn't teach us how to recognize a dog by measuring the shape of its nose or the contours of its body. We learned to recognize a dog by being shown multiple examples and being corrected when we made the wrong guess. In other words, when we were born, our brains provided us with a model that described how we would be able to see the world. As we grew up, that model would take in our sensory inputs and make a guess about what we were experiencing. If that guess was confirmed by our parents, our model would be reinforced. If our parents said we were wrong, we'd modify our model to incorporate this new information. Over our lifetime, our model becomes more and more accurate as we assimilate more and more examples. Obviously all of this happens subconsciously, without us even realizing it, but we can use this to our advantage nonetheless.

Deep learning is a subset of a more general field of artificial intelligence called machine learning, which is predicated on this idea of learning from example. In machine learning, instead of teaching a computer a massive list of rules to solve the problem, we give it a model with which it can evaluate examples, and a small set of instructions to modify the model when it makes a mistake. We expect that, over time, a well-suited model would be able to solve the problem extremely accurately.

Let's be a little bit more rigorous about what this means so we can formulate this idea mathematically. Let's define our model to be a function ℎ(x,𝞠). The input x is an example expressed in vector form. For example, if x were a grayscale image, the vector's components would be pixel intensities at each position, as shown in Figure 1-3.

Figure 1-3. The process of vectorizing an image for a machine learning algorithm
The input 𝞠 is a vector of the parameters that our model uses. Our machine learning program tires to perfect the values of these parameters as it is exposed to more and more examples. We'll see this in action and in more detail in Chapter 2.

To develop a more intuitive understanding for machine learning models, let's walk through a quick example. Let's say we wanted to determine how to predict exam performance based on the number of hours of sleep we get and the number of hours we study the previous day. We collect a lot of data, and for each data point x = [x₁ x₂]T, we record the number of sleep we get (x₂), and whether we performed above or below the class average, Our goal, then, might be to learn a model ℎ(x,𝞠) with parameter vector 𝞠 = [𝞠₀ 𝞠₁ 𝞠₂]T such that:

In other words, we guess that the blueprint for our model ℎ(x,𝞠) is as described above (geometrically, this particular blueprint describes a linear classifier that divides the coordinate plane into two halves). Then, we want to learn a parameter vector 𝞠 such that our model make the right predictions (-1 if we perform below average, and 1 otherwise) given an input example x. This model is called a linear perceptron, and it's a model that's been used since the 1950s. Let's assume our data is as shown in Figure 1-4.

Figure 1-4. Sample data for our exam predictor algorithm and a potential classifier

Then it turns out, by selecting 𝞠 = [-24 3 4]τ, our machine learning model makes the correct prediction on every data point:

An optimal parameter vector 𝞠 positions the classifier so that we make as many correct predictions as possible. In most cases, there are many ( or even infinitely many) possible choices for 𝞠 that are optimal. Fortunately for us, most of the timethese alternatives are so close to one another that the difference is negligible. If this is not the case, we may want to collect more data to narrow our choice of  𝞠.

While the setup seems reasonable, where are still some pretty significant questions that remain. First off, how do we even come up with an optimal value for the parameter vector  𝞠 in the first place? Solving this problem requires a technique commonly known as optimization. An optimizer aims to maximize the performance of a machine learning model by iteratively tweaking its parameters until the error is minimized. We'll begin to tackle this question of learning parameter vectors in more detail in Chapter2, when we describe the process of gradient descent. In later chapters, we'll fry to find ways to make this process even more efficient.

Seound, it's quite clear that this particular model (the linear perceptron model) is quite limited in the relationships it can learn. For example, the distributions of data shown in Figure 1-5 cannot be described well by a linear perceptron.

Figure 1-5. As our data takes on more complex forms, we need more complex models to describe them
But these situations are only the tip of the iceberg. As we move on to much more complex problems, such as object recognition and text analysis, our data becomes extremely high dimensional, and the relationships we want to capture become highly nonlinear. To accommodate this complexity, recent research in machine learning has attempted to vuild models that resemble the structures utilized by our brains. It's essentially this body of research, commonly referred to as deep learning, that has had spectacular success in tackling problems not only for surpass other kinds of machine learning algorithms, but also rival(or even exceed!) the accuracies achieved by humans.

The Neuron
The foundational unit of the human brain is the neuron. A tiny piece of the brain, about the size of grain of rice, contains over 10.000 neurons, each of which forms and average of 6,000 connections with other neurons. It's this massive biological network that enalbes us to experience the world around us. Our goal in this section will be to use this natural structure to build machine learning models that sol ve problems in an analogous way.

At its core, the neuron is optimized to receive information from other neurons, process this information in a unique way, and send its result to other cells. This process is summarized in Figure 1-6. The neuron receives its inmputs along antennae-like structures called dendrites. Each of these incoming connections is dynamically strengthened or weakened based on how oftern it is used(this is how we learn new concepts!), and it's the strength of each connection that determines the contribution of the input to the neuron's output. After being weighted by the strength of their respective connections, the inputs are summed together in the cell body. This sum is then transformed into a new signal that's propagated along the cell's axon and sent off to other neurons.

Figure 1-6. A functional description of a biological neuron's structure
We can translate this functional understanding of the neurons in our brain into an artificial model that we can represent on our computer. Such a model is described in Figure 1-7, leveraging the approach first pioneered in 1943 by Warren S. McCulloch and Walter H. Pitts. Just as in biological neurons, our artificial neuron takes in some number of inputs, x₁, x₂,...,xₙ, each of which is multiplied by a specific weight, w₁, w₂,...,wₙ These weighted inputs are, as before, summed together to produce the logit of the neuron,
.
In many cases, the logit also includes a bias, which is constant ( not shown in the figure). The logit is then passed through a function f to produce the output y = f(z). This out put can be transmitted to other neurons.

Figure 1-7. Schematic for a neuron in an artificial neural net

We'll concolude our mathematical discussion of the artificial neuron by re-expressiong its functionality in vector form. Let's reformulate the inputs as a vector x =  [x₁ x₂ ... xₙ] and the weights of the neuron s w = [w₁ w₂ ... wₙ] . Then we can re-express the output of the neuron as y = f(x.w + b), where b is the bias term. In other words, we can compute the output by performing the dot product of the input and weight vectors, adding in the bias term to produce the logit, and then applying the transformation function. While this seems like a trivial reformulation, thinking about neurons as a series of vector manipulations will be crucial to how we implement them in software later in this book.

- Expressiong Linear Perceptrons as Neurons
In "The mechanics of Machine Learning" on page 3, we talked about using machine learning models to capture the relationship between success on exams and time spent studying and sleeping. To tackle this problem, we constructed a linear perceptron classifier that divided the Cartesian coordinate plane into two halves:


As shown in Figure 1-4, this is an optimal choice for 𝞠 because it correctly classifies every sample in our dataset. Here, we show that our model h is easily using a neuron.
Consider the neuron depicted in Figure 1-8. The neuron has two inputs, a bias, and uses the function:


It's very easy to show that our linear perceptron and the neuronal model are perfectly equivalent. And in general, it's quite simple to show that singular neurons are strictly more expressive than linear perceptrons. In other words, every linear perceptron can be expressed as a single neuron, but single neurons can also express models that cannot be expressed by any linear perceptron.
Figure 1-8. Expressing our exam performance perceptron as a neuron
- Feed-Forward Neural Networks
Although single neurons are more powerful than linear perceptrons, they're not nearly expressive enough to solve complicated learning problems. There's a reason our brain is made of more than one neuron, For example, it is impossible for a single neuron to differentiate handwritten digits. So to tackle much more complicated tasks, we'll have to take our machine learning model even further.

The neurons is the human brain are organized in layers. In fact, the human cerebral cortex (The structure responsible for most of human intelligence) is made up of six layers. Information flows from one layer to another until sensory input is converted into conceptual understanding. For example, the bottommost layer of the visual cortex receives raw visual data from the eyes.  This information is processed by each layer and passed on to the next until, in the sixth layer, we conclude whether we are looking at a cat, or a soda can, or an airplane. Figure 1-9 shows a more simplified version of these layers.

Figure 1-9. A simple example of a feed-forward neural network with three layers(input, one hidden, and output) and three neurons per layer

Borrowing from these concepts, we can construct an artificial neural network. A neural network comes about when we start hooking up neurons to each other, the input data, and to the output nodes, which correspond to the network's answer to a learning problem. Figure 1-9 demonstrates a simple example of a artificial neural network, similar to the architecture described in McCulloch and Pitt's work in 1943. The bottom layer of the network pulls in the input data. The top layer of neurons (output nodes) computes our final answer. The middle layer(s) of neurons are called the hidden layers, and we let
 be the weight of the connection between the  neuron in the  layer with theneuraon in the layer. These weights constitute our parameter vector, 𝞠, and just as before, our ability to solve problems with neural networks depends on finding the optimal values to plug into 𝞠.

We not that in this example, connections only traverse from a lower layer to a higher layer. There are no connections between neurons in the same layer, and there are no connections that transmit data from a higher layer to a lower layer. These neural networks are called feed-forward networks, and we start by discussing these networks because they are the simplest to analyze. We present this analysis (specifically, the process of selecting the optimal values for the weights) in Chapter 2. More complicated connectivities will be  addressed in later chapters.

In the final sections, we'll discuss the major types of layers that are utilized in feedforward neural networks. But before we proceed, here's a couple of important notes to keep in mind:

1. As we mentioned, the layers of neurons that lie sandwiched between the first layer of neurons (input layer) and the last layer of neurons (output layer) are called the hidden layers. This is where most of the masic is happening when the neural net tries to solve problems. Whereas (as in the handwritten digit example) we would previously have to spend a lot of time identifying useful features, the hidden layers automate this process for us. Oftentimes, taking a look at the activities of hidden layers can tell you a lot about the features the network has automatically learned to extract from the data.

2. Although in this example every layer has the same number of neurons, this is neither necessary nor recommended. More often than not, hidden layers have fewer neurons than the input layer to force the network to learn compressed representations of the original input. For example, while our eyes obtain raw pixel vlaues from our surroundings, our brain thinks in terms of edges and contours. This is because the hidden layers of biological neurons in our brain force us to come up with better representations for everything we perceive.

3.It is not required that every neuron has its output conneted to the inputs of all neurons in the next layer. In fact, selecting which neurons to connect to which other neurons in the next layer is an art that comes from experience. We'll discuss this issue in more depth as we work though various examples of neural networks.

4. The inputs and outputs are vectorized representations. For example, you might imagine a neural network where the inputs are the individual pixel RGB values in an image represented as a vector (refer to Figure 1-3). The last layer might have two neurons that correspond to the answer to our problem: [1, 0] if the image contains a dog, [0,1] if the image contains a cat, [1, 1] if it contains both and [0, 0] if it contains neither. 

We'll also observe that, similarly to our reformulation for the neuron, we can also mathematically express a neural network as a series of vector and matrix operations.
Let's consider the input to thelayer of the network to be a vector x =  [x₁ x₂ ... xₙ].
We'd like to find the vector y = [y₁ y₂ ... yₘ] produced by propagating the input through the neurons. We can express this as a simple matrix multiply if we construct a weight matrix W of size n * m  and a bias vector of size m. In this matrix, each column corresponds to a neuron, where the element of the column corresponds to the weight of the connection pulling in the element of the input. In other words, y = ƒ(WTx + b), where the transformation function is applied to the vector elementwise. This reformulation will become all the more critical as we begin to implement these networks in software.

- Linear Neurons and Their Limitations
Most neuron types are defined by the function f they apply to their logit z. Let's first consider layers of neurons that use a linear function in the form of f(z) = az +b. For example, a neuron that attempts to estimate a cost of a meal in a fast-food restaurant would use a linear neruon where a = 1 and b = 0, In other words, using f(z) = z and weight equal to the price of each item, the linear neuron in Figure 1-10 would take in some orderd triple of servings of burgurs, fries, and sodas and output the price of the combination.


Figure 1-10. An example of a linear neuron
Linear neurons are easy to compute with, but they run into serious limitations. In fact, it can be shown that any feed-forward neural network consisting of only linear neurons can be expressed as a network with no hidden layers. This is problematic because, as we discussed before, hidden layers are what enable us to learn important features from the input data. In other words, In order to learn complex relationships, we need to use neurons that employ some sort of nonlinearity.

- Sigmoid, Tanh, and ReLu Neurons
 There are three major types of neurons that are used in practice that introduce nonlinearities in their computations. The First of these is the sigmoid neuron, which uses the function:








2018년 2월 7일 수요일

Unsupervised Learning and Preprocessing

1. Types of Unsupervised Learning


4.3 수치 미분

경사법에서는 기울기(경사) 값을 기준으로 나아갈 방향을 정합니다. 기울기란 무엇인지, 또 어떤 성질이 있는지를 설명하기에 앞서, 이번 절에서는 학생 때 배운 '미분'부터 복습해 보겠습니다.

4.3.1 미분
여러분이 마라톤 선수고 처음부터 10분에 2km씩 달렸다고 해봅시다. 이때의 속도는 간단히 2/10 = 0.2[km/분]이라고 계산할 수 있습니다. 즉, 1분에 0.2km만큼의 속도(변화)로 뛰었다고 해석할 수 있습니다.
이 마라톤 예에서 '달린거리'가 '시간'에 대해서 얼마나 변화했는가를 계산했습니다. 다만 여러기에서 10분에 2km를 뛰었다는 것은, 정확하게는 10분 동안의 '평균 속도'를 구한 것이죠. 미분은 '특정 순간'의 변화량을 뜻합니다. 그래서 10분이라는 시간을 가능한 한 줄여 (직전 1분에 달린거리, 진전 1초에 달린 거리, 진전 0.1초에 달린 거리,....식으로 갈수로 간견을 줄여)한 순간의 변화량(어느 순간의 속도)을 얻는 것이죠.
이처럼 미분은 한순간의 변화량을 표시한 것입니다. 수식으로 다음과 같습니다.

좌변은 f(x)의 x에 대한 미분(x에 대한 f(x)의 변화량)을 나타내는 기호입니다. 결국, x의 '작은 변화'가 함수f(x)를 얼마나 변화시키느냐를 의미합니다. 이때 시간의 작은 변화, 즉 시간을 뜻하는 h를 한없이 에 가깝게 한다는 의미를 lim로 나타납니다.

4.3.2 수치 미분의 예
앞 절의 수치 미분을 사용하여 간단한 함수를 미분해 봅시다. 우선 다음과 같은 2차 함수입니다.

y = 0.01x2 + 0.1x
파이썬으로 구현하면 다음과 같이 됩니다.

def function_1(x):
    return 0.01*x**2+0.1+x




2018년 2월 6일 화요일

1.1 벡터와 공간

그럼 바로 벡터부터 시작합니다. 어떤 분야에서라도 '몇 개의 수치를 한 곳에 모아 한 덩어리로 다루고 싶다'라고 생각할 것입니다. 예를 들어 센서 열 개를 탑재한 로봇이라면 거기에서 얻을  수 있는 관측치 열 개를 한 덩어리로 다루고 싶을 것입니다.

1.1.1 우선적인 정의: 수치의 조합을 정리하여 나타내는 기법

수를 나열한 것을 벡터라고부릅니다. 예를 들면 다음과 같습니다.

성분수를 명시하고 싶을 때는 각각 2차원 벡터, 3차원 벡터, 5차원 벡터라고 부릅니다. 벡터라고 하면 특별히 미리 말하지 않는 한 이처럼 세로로 늘어선 '종벡터'라고 약속합니다. (2,3,5,8)처럼 가로로 늘어선 '횡벡터'도 있지만, 이 책에서는 종벡터를 기본으로 합니다. 단 종벡터를 정말로 세로로 표기하면 공간만 차지하므로 다음과 같이 표기하겠습니다.
(2,3,5,8)T

T는 전치를 뜻하는 Transpose의 T입니다.

1.1 왜 그렇게 종벡터를 좋아하나요?
'변수 x에 함수 f를 적용하다'라는 작업을 일반적으로 f(x)라고 씁니다. 이와 같은 어순으로 '벡터 x에 행렬 A(로 나타내지는 함수)를 적용하다'라는 작업을 행렬의 곱으로 Ax라 쓰기 위해서 입니다 (1.2.1절). 만약 x가 횡벡터라3.면 xA처럼 '대상 -> 작업'이라는 어순이 되어 버립니다. 단, 객체지향에 익숙한 사람에게는 f(x)보다는  x.f쪽이 자연스러울지도 모르겠습니다.

1.2 '수'란?

이 책에서는 '실수'또는 '복소수'로 읽어주세요. 실수인지 복소수인지에 따라 이야기가 달라지는 경우에는 정확히 명시해두었습니다. 또한, 성분이 실수인 것을 명시하지 않았다면 '실벡터'나 '실행렬'로 부르고, 성분이 복소수인 것을 명시하지 않았다면 '복소벡터'나 '복소행렬'로 부릅니다. 만약을 대비해 용어를 확인해 둡시다.

자연수        0, 1, 2, 3,.....
정수        ...., -2, -1, 0, 1, 2,.....
유리수      (정수)/(정수)로 표현되는 수
실 수       3.14159265....처럼 (무한)소수로 표현되는 수
복소수    허수 단위 i(i2 = -1)를 사용하여 (실수) + (실수)i로 표현되는 수

i라는 기호는 허수 단위 이외에 단순한 변수명으로 사용됩니다. 물론 문맥상 분명하므로 햇갈릴까 걱정하지 않아도 됩니다.

'데이터 구조'를 정의했으면 그에 대한 연산도 정의합시다. 벡터의 덧셈과 정수배를 다음과 같이 정의합니다.

덧셈   같은 차원의 벡터에 대해

정수배 임의의 수 c 에 대해


덧붙여서 말하자면 횡벡터의 덧셈과 정수배도 똑같이 정의합니다.

벡터는 x,v,e 처럼 두꺼운 글씨로 쓴다고 약속합니다. 그냥 숫자와 벡터를 확실히 구별하고 의식하도록 습관을 들이기 위해서 입니다. 스스로 노트에 정리할 때도 생략하지 말고 x,v,e 처럼 꼭 두꺼운 글자로 쓰도록 합니다. 특히 영벡터(모든 성분이 0인 벡터)를  o = (0, 0, ....0)T라는 기호로 씁니다. 또한, (-1)x 는 -x로 줄여 쓰고, x + (-y) 를 x -y라고 줄여 씁니다. 2x + 3y라고 쓰면 (2x) + (3y)처럼 정수배를 먼저 계산 합니다.

수 c, c'와 벡터 x,y에 대한 다음과 같은 성질은 '한분에' 알 수 있을 것입니다.

1.1.2 '공간'의이미지

2차원 벡터는 모눈종이 위에 점으로 찍을 수 있습니다(그림 1-1), (3,5)T 라면 '가로축 3, 세로축 5'의 위치에, (-2.2, 1.5)T라면 '가로축 -2.2, 세로축 1.5'의 위치에, 영벡터  o=(0,0)는 원점 0과 같은 상태입니다. 이와 같이 3차원 벡터도 3차원 공간 안 어딘가에 한 점으로 나타낼 수 있습니다.

이런 식으로위치에 대응시키는 것을 강조할 때는 '위치 벡터'라고 부르기도합니다.

위치라는 해석 외에 원점 0에서 그 위치를 향하는 '화살표'라는 해석도 있습니다. 덧셈과 정수배를 도형으로 해석하려면 화살표 쪽이 더 잘 어울립니다. 덧셈은 화살표의어어 붙임, 정수배는 길이를 늘이고 줄입니다(그림 1-2). '-3배'라면, 물론 '반대 방향으로 원래 길이의 3배'가 됩니다.

1.5 일차원 벡터란 그냥 숫자인가요?
일차원 벡터(a)와 수 a를 동일시하는 것은 자연스러운 현상이라고 생각합니다. 둘 모두 직선상의 한 점으로 나타나니까요. 단, 단위를 취하는 벙법에 따라 값이 변하는 것에는 주의합시다. 다음 절에서 설명할 '기저'와 관련된 문제입니다. 1.11, 1.20도 참고하세요. 또한, 대부분의 프로그래밍 언어에서는 '크기 1인 배열'과 '수치'는 다른 것이므로 명시적인 변환 작업이 필요할 것입니다.

1.1.3 기저

우주에는 위도 없고 오른쪽도 없다

앞 절에서 2차원 벡터를 평면 위의 점이라고 해석했습니다. 앞에서는 평면에 모눈종이 눈금이 그려져 있었습니다만, 본래 우주에는 위라든지 오른쪽이라든지 특별한 방향이란 게 없을 것입니다. 여기서 마음껏 눈금을 지워봅시다.
눈금도 특별한 방향도 없는 오로지 평평한 평면입니다. 표식이 되는 것은 원점 o하나뿐입니다. 처음에는 조금 불안하지만, 이런 세계에서도 잘 해나갈 수 있습니다. 즉, '덧셈'도 '정수배'도, '화살표 해석'을 하면 수행 기능 합니다. 없어도 해나갈 수 있는 것은 없는 채로 생각하는 것이 스마트하지요. 이처럼 '덧셈'과 '정수배'가 정의된 세계를 선형 공각이라 부릅니다. 벡터 공간이라고 부르는 사람도 있습니다.

이 스마트한 세계에서의벡터는 화살표 해석을 강종하여 x, y, e처럼 표기합니다. 숫자의나열로서의 벡터는 x, 화살표로서의 벡터는 x  로 구분해서 쓰는 것은 이 책에서만 사용하는 약속입니다.

선형 공간은 우리가 사는 현실 공간의 어느 측면을 어느 수준에서 추상화한 것입니다. 완전한 복제가 아닌 '기능 축소판'이므로 오해하지 말아 주십시오. 이 세계에서는 영벡터만 특별하고, 그 외에는 어느 화살표도 대등합니다. 적용되는 것은 덧셈과 정수배뿐입니다. 뭐든지 직선형입니다.

여기서 이 세계에는 '길이'나 '각도'가 정의되지 있지 않다는 것에 주의해 주십시오. 다른 방향의 벡터끼리 대소를 비교하는 방법은 없습니다. '회전(=길이를 유지하며 방향을 바꾸다)'이라는 작업도 정의할 수 없습니다. '본래의' 선형 공간에 이런 기능은 없습니다.

기준을 정하며 번지를 매기자
자, 스마트해진 것은 좃습니다만, 이 상태로는 특정 벡터 v를 지정하는데 '여기'라고 손가락으로 가리킬 수 밖에 없습니다. 역시 조금 불편합니다. 말로도 의치를 전할 수 ㅣㅇㅆ도록 이 세계에서 '번지(좌표)'를 매겨 줍시다.
우선 기준이 되는 벡터 e1, e2가 무엇인지 정합니다. 예를 들어 그림 1-4처럼요, 기준을 정하면 e1를 3보 e2를 2보'처럼 말하여 벡터 v의 위치를 지정할 수 있습니다.
즉, 다음과 같이 말하는 것입니다.
v = 3e1 + 2e2
이런 '기준이 되는 한 쌍의 벡터'를  기저, '각 기준에서 몇 보 나아가는가'를 좌표라고 합니다. 위의 예라면 '기저(e1, e2) 에 대한 벡터 v=(3,2)T입니다., 또한, '기저'라고하면 팀( e1, e2)를 말하며, 팀의 멤버인 e1나 e2는 기저 벡터라고 부릅니다.
기준을 잡는 방법은 여러 가지로 생각할 수 있습니다. 특히 그림 1-5 처럼 잡으면 제일 처음에 생성한 모눈종이 눈금과일치하네요.

단, 벡터를 몇 개쯤 가져와서 묶는 다고 뭐든 기저가 되는 것은 아닙니다. 다음 절에서는 기저라고 부를 수 있는 자격에 대해 이야기 하겠습니다.

1.1.4 기저가 되기 위한 조건
벡터의 조합을 기저라 부르는 것은 다음 두 가지 조건을 만족시켰을 때뿐입니다.

1. (지금 생각하고있는 공간 안의) 어떤 벡터 v라도 라는 형태로 나타낼 수 있다.

2. 게다가 나타내는 방법은 한 가지뿐이다.

조건 1은 당연한 요청입니다. 좌표로 이야기하고 싶은데 나타낼 수 없는 것이 있으면 고란합니다.

조건2도 성가심을 피하기 위해서 꼭 요청하고 싶은 부분입니다. 그렇지 않으면 곤란합니다.

1.1.6 좌표에서의 표현
사실 좌표에'기저'를 지정하지 않으면 의미가 없습니다. 이는 당영한 것으로 "후지산의 높이는 3776이다"라고 하면 무슨 뜻인지 알 수 없습니다. "3776m다"라고 단위를 붙이고 나서야 의미를 지니는 것과 같습니다. 이때 값'3776'이 좌표, 단위'm'가 기저에 해당합니다.
그렇다고 해도 매번 기저를 쓰는 것은 귀찮고 위압적인 느낌이 듭니다. 다음 절 이후부터는 기저를 생략하고 좌표 v만 표시하도록 하니다. 어떤 기저를 정하여 계속 고정시키 두므로 일일이 쓰지 않는 다는 입장입니다. 평소에는 좌표 v를 '벡터'라고 생각해도 상관없습니다만, 마음에 여유가 생겼을 때는 배후에 있는 기저를 의힉하고 봐 주십시오.
좌표만으로 이야기하려면 "덧셈과 정수배를 좌표로 말하면 어찌되는가"를 확인해 두어야 합니다. 결과는 별 것 없어서 "어떤 기저를 취하여 좌표를 표시해도 덧셈과 정수배는 식(1.1)과 식 (1.2)처럼 좌표 성분마다 덧셈과 정수배가 된다"입니다. 실제로 벡터 과 수 에 대해 다음 내용을 바로 확인 할 수 있습니다.

또한, 두 가지 이상의 기저가 등장하는 경우도 가끔 있습니다. 이 경우에도 물론 기저를 명시합니다. 두 기정에 대해 한 쪽의 좌표에서 다른 쪽의 좌표를 구하는 '좌표 변화' 이야기는 '행렬'을 도입한 후 1.2.11절에 설명합니다.

1.2 행렬과 사상
벡터라는 '대상'을 알았으니 다음 관심읔 대상 간의 '관계'입니다. 이 관계를 나타내기 위해 행렬이 등장합니다.

1.2.1 우선적인 정의: 순수한 관계를 나타내는 편리한 기법

수를 직사각형 형태로 나열한 것을 행렬이라고 부릅니다.
크기를 명시하고 싶은 경우에는 각각 2*2 행렬, 2*3행렬, 5*3 행렬처럼 부릅니다. '행렬'이므로 '행'과 '열'의 순으로 표기한다고 기억해 주십시오. 특히 행 수와 열 수가 같은 행렬을 정방행렬이라고 부릅니다. 크기를  명시하고 싶은 경우는 2*2 또는 2차 정방행렬, 3*3 또는 3차 정방행렬이라 부릅니다.
행렬 A의 i행과 j열의 값을 A의(i,j)성분이라고 합니다. 예를 덜어 앞에서 제시한 세 행렬 중 중아의 행렬에서  (2,1) 성분은 \sqrt{7}\ 이고, (1,3) 성분은 1/7입니다. (i, j) 성분이라 할 때의 순서도 '행', '열'입니다. 또한 다음과같이 쓸때 첨자 순서도 일반적으로 '행','열'입니다.

귀찮아서 이를 '3*4 행렬 A=(aij)'등으로 줄여 쓰는 경우도 있습니다. 일반적으로 행렬은 알파벳 대문자로, 성분은 소문자로 씁니다.

행렬의 덧셈과 정수배를 다음과 같이 정의합니다.
덧셈같은 크기의 행렬에 대해

정수배 임의의 수 c에 대해

다음과 같은 표기법 약속은 벡터의 경우와 같습니다.
또한, 행렬과 벡터의 곱을 정의하겠습니다. 그 전에 잠시 다음과 같은 산수 문제를 생각해 주십시오.
고기를 x그램, 콩을 x그램, 쌀을 x그램 샀습니다. 합계는 얼마일까요? 또한, 총 몇 칼로리일까요?

각각의 답인  y(돈), y(칼)은 다음과 같습니다.

y(돈) = a(돈고)x(고) + a(돈콩)x(콩) + a(돈쌀)x(쌀)
y(칼) = a(칼고)x(고) + a(칼콩)x(콩) + a(칼쌀)x(쌀)

식에서 a(돈고)는 고기 1그램당 가격, a(칼고)는 고기 1그램당 칼로리입니다.
이 식들을 정리하면 다음과 같이 쓸 수 있습니다.
'요인'인 x(고),x(콩),x(쌀)과 '요소'인 a가 각각 하나에 정리되어 깔끔하게 보기 좋아집니다. 이것이 '행렬과 벡터의 곱'입니다.
곱 m*n행렬과 n차원 벡터에 대해

곱에 대해서는 다음 사항을 주의합니다.
- 행렬과 벡터의 곱은 벡터
- 행렬의 열 수(가로폭)가 '입력'의 차원 수, 행 수(높이)가 '출력'의 차원 수
- 입력의 종벡터를 가로로 넘겨 딱딱 계산하는 느낌

자, 식(1.5)와 식(1.6)을 다시 새겨둡시다. 이 식들이 나타내는 것은 요인 x(고), x(콩), x(쌀)에서 결과 y(돈), y(칼)이 결정될 때 상승 효과(세트 할인)나 규모에 의한 변화(대량 매수 할인)등이 없는 '순수'한 관계입니다. 그 덕분에 a(돈고)x(고) + a(돈콩)x(콩) + a(돈쌀)x(쌀)과 같은 형태의 식은 다루기 쉽고, 예측하기도 좋아 깔끔하게 노의할 수 있습니다. 이 '순수함'을 멋있게 바꿔 말하면 "정의한 '벡터의 덧셈과 정수배'를 제대로 유지하다"라고 표현됩니다. 이는 행렬 A에 대해 ' x + y = z 에서 Ax+ Ay= Az' , 'cx = y에서 c(Ax) = Ay'라는 의미입니다.
정리하면 행렬이란 순수한 관곌르 나타내는 편리한 기법입니다.

1,15 행렬이 '순수한 관계'라는 것을 알았습니다. 반대로 '순순한 관계'는 모두 행렬이라 생각해도 될까요?
일반ㄴ적으로 f(x + y) = f(x) + f(y), f(cx) = cf(x)라는 성질을 지닌 사상 f를 선형 사상이라고 합니다(x, y는 같은 크기의 벡터, c는 수, f(x)의 값은 벡터라고 합니다). 즉, 본문을 고쳐 말하면 '행렬  A를 곱한다는 사상은 선형 사상이다'라는 것입니다. 그 반대로 말할 수 있어서 임의의 선형 사상f는 '행렬을 곱한다'는 형태로 반드시 쓸 수 있습니다. 실제로 e1 = (1,0,0,0,....,0)T, e2=(0,1,0,0,....,0)T.....를 각각 입력한 때의 출력을 ai = f(ei) 로 두면 입력 x=(x1, ...,xn)T에 대한 출력은  f(x) = x1a1+....+xnan이 됩니다. 종벡터 a1, ....an을 나열한 행렬 A = (a1, a2,....,an)를 사용하면 이것은 f(x)= Ax로 쓸 수 있습니다(1.2.9절 '블록행렬'). 멋있게 말하면 행렬이란 '선형 사상을 좌표 성분으로 표시한 것'입니다.

1.2.2 여러 가지 관계를 행렬로 나타내다(1)
앞 절에서 설명했듯이 "행렬을 곱하다"는 순수한 관계'를 나타냅니다. "상승 효과나 규모 효과가 없고, 단순히 가 요인의 합계다'라는 순수한 관계는 여기저기서 맞딱드리게 됩니다. 대상 자체가 곧은 경우도 있고, 복잡한 것에 대한 근사 모델로 가정된 경우로 있는 것은 0.2절 '근사 수단으로 사용하기 편리하다'에 서술한 대로입니다.

학 거북이 계산
학이 x(학)마리, 거북이가  x(거북)마리 있다면 머리의 개수  y(머리)와 다리의 개수  y(다리)는 다음과 같습니다.
 y(머리) = a(학머리)x(학) + a(거북머리)x(거북) = x(학) + x(거북)
 y(다리) = a(학다리)x(학) + a(거북다리)x(거북) = 2x(학) + 4x(거북)
 a(학머리)=1 은 학 한 마리의 머리 개수,  a(거북다리) = 4는 거북이 한 머리의 다리 개수라는 형태 입니다. 이를 행렬로 쓰면 다음과같습니다.
이것도 상승 효과나 규모 효과가 없는 순수한 관꼐네요. 학 열 마리의 다리 개수는 학 한 마리의 다리 개수를 단순히 10배하면 됩니다. 집단 A와 집단B를 합쳐 놓은 머리의 총 개수는 A의 머리 개수와 B의 머리 개수를 단순히 더하면 됩니다.

제품과 필요 원료
다음과같은 예도 생각할 수 있습니다.
- 제품 1을 한개 만드는 데는 원료 1, 2, 3이 각각 a11, a21, a31 그램씩 필요
- 제품 2을 한개 만드는 데는 원료 1, 2, 3 이 각각 a12, a22, a32 그램씩 필요

지금 제품 1,2를 각각 x1, x2개 만든다면 원료 1,2,3의 필요량 y1,y2,y3은 다음과 같이 구할 수 있습니다.

그 외 여러 가지
그 외에도 다양한 경우에서  y = Ax 형태의 관계를 만나게 됩니다. 자세히 설명하려면 각 분야의 전문 지식이 필요하므로 여기서는 예만 들어 보겠습니다. 다음과 같은 것이 있습니다.

- 회로망 이론( LCR 회로의 전류와 전압)
- 신호 처리(선형 필터, 푸리에 변환, 웨이블릿 변환)
- 제어 이론(선형 시스템)
- 통계 분석(선형 모델)

y= Ax라는 형태로 노골적으로 쓰진 않아도 그렇게 해석 가능한 경우도 있습니다.

1.2.3 행렬은 사상이다.
n차원 벡터 x에 m*n 행렬 A를 곱하면 m차원 벡터 y = Ax가 얻어집니다. 즉, 행렬A를 지정하면 벡터를 다른 벡터에 옮기는 사상이 결정됩니다. 사실 이것이야말로 행렬의 가장 중요한 기능입니다. 지금부터는 행렬을 보면 단순히 '수가 나열되어 있다'라고 생각하지 말고, '사상이 주어졌다'고 생각해 주십시오. 계속해서 강조하겠습니다.
행렬은 사상이다.
사상이라는 언어는 조금 위압감이 있을지도 모릅니다. 일반적으로 쓰이는 '변환'이란 말도 있지만, 수학용어로서의 변환에는 '대등한 것에 이동한다'라는 의미가 있습니다. n차원 공간에서 m차원 공간이라는 다른 세계에 옮기는 것을 변환이라고 부를 수 없으므로 사상이라는 조금 더 넓은 언어를 사용했습니다.

자, 이 설명만으로는 아직 '점을 점으로옮긴다'는 이미지겠지요. 여기서 조금 더 힘을 내 '공간 전체가 어떻게 변하는 가'를 떠올릴 수 있다면 선형대수가 매우 알기 쉬워질 것입니다. '백문이 불여일견, 이 장에서는 이 변형을 애니메이션 프로그램으로 실제로 관찰해 봅시다.

1.2.4 행렬의 곱 = 사상의 합성
행렬끼리의 곱을 다음과 같이 정의 합니다.
곱 k*m 행렬 B = (bij)와 m*n 행렬 A = (ajp)에 대해

각 행렬의 크기에 주의합니다. k * m 행렬의 곱이 k * n 입니다.

계산은 다음 방법을 추천합니다.
1. 오른쪽 행렬을 세로 단락으로 분해한다.
2. 분해한 각각에 왼쪽 행렬을 곱한다(행렬과 벡터의 곱으로서).
3. 결과를 접착

구체적으로는 다음과 같은 요령입니다.

처음 보면 "이건 뭐야"라는 반응이 보통입니다. 이는 '사상의 합성'을 나타냅니다. 벡터 x를 우선 사상 A로 날려버리고, 목적한 곳 y = Ax역시 사상 B 로 날렸다고 합시다. 최종 종착지는 z = B(Ax) 입니다. 여기서 행렬의 곱 BA는 x를 z에 단숨에 날리는 사상인 것입니다.
요약하면 'A하고, B한다'가 곱 BA인 것입니다. 식으로 쓰면 다음과 같습니다.
(BA)x = B(Ax)
어떠한 x에도 성립합니다. 일단 이해가 되면 같은 것을 굳이 구별할 필요가 없으므로 보통은 괄호를 생략하고 BAx처럼 씁니다. (BA)x로 해석해도,  B(Ax)로 해석해도 답은 같습니다.
이 '의미'와 '계산법'의 관계는 그림 1-13을 보면서 이미지화 해보세요.  B의 폭(열수)과 A의 높이(행 수)가 맞지않으면 안되는 것도 이 그림을 보고 이해할 수 있을 것입니다.

1.17 A하고, B한다면  AB가 아닌가요?
'f한 것을 g한다'는 g(f(x))이지요, 옐르 들어 '대문자로 출력한다'라면 putchar(toupper(x))입니다. 이와 같은 의미로  BAx가 정답입니다. 이 스타일로 쓰는 한 조각 순서와 표기 순서가 반대인 것은 어쩔 수 없습니다.

다음으로 세 행렬 A, B, C의 곱도 생각해 봅시다. 예상대로 'A하고, B하고,  C하는 것은  CBA'입니다. 여기서 포인트는 다음 어느 것이어도 결과가 같다는 것입니다.

- 'A하고, B한다'를 하고 나서 C를 한다.
- A를 하고 나서 'B하고,  C한다'를 한다.
식으로 쓰면 다음과 같습니다.
C(BA) = (CB)A
마찬가지로 행렬이 네 개인 경우를 봅시다.
D(C(BA)) = D((CB)A) = (D(CB))A = (DC)(BA)
이렇게 괄호를 붙여도 결국 같습니다. 그러므로 보통은 괄호 따위 붙이지 않고 CB
A 나 DCBA처럼 씁니다.
그러나 BA와 AB는 같지 않습니다. 우선 A,B의 크기에 따라 처음부터 곱이 정의되지 않습니다.
또한, 만약 가능해도 결과는 대부분 다릅니다.
사실 행렬 A는 공간을 '돌린다', 행렬 B는 공간을 '가로로 넓히다'라는 효과가 있습니다. A와  B의 곱은 BA라면 돌려서 가로로 늘리고, AB라면 가로로 넓혀서 돌리는 것이 됩니다. 결과는 서로 다릅니다.

1.18 곱의 정의식(1.9)의 어디를 어떻게 보면 '이것은 사상의 합성이다' 라고 알 수 있나요?

행렬의 각 열은 각 축 방향의 단위 벡터 e1, .... em의 목적지가 된다는 지적을 우선 떠올려주세요(1.2.3절 '행렬은 사상이다'). 지금 'A하고, B한다'에 대응하는 행렬을 C라고 합시다. C의 1열인 c1을 알기 위해서는 e1 = (1,0,,,,,0)T가 C에서 어디로 갈지를 알아보면 됩니다. 즉, e1에 A를 고하여 거기에 더욱이 B를 곱한 어느 곳에 가는가 입니다.

1스텝의 Ae1은 물론 A의 1열a1이 됩니다. 그러므포 2스텝의 목적지는 c1 = Ba1입니다. 다른 것도 같으므로 C의 i열 ai에 B를 곱한 것디 됩니다. 다시 말해서  C=BA를 구하기 위해서는 행렬과 벡터의 곱 Ba1, ,,,, Bam을 계산해 두고, 그 결과를 나열하여 붙이면 됩니다. 이것은 좀 전에 서술한 '암기법' 그 자체입니다. 그러므로 '곱은 사상의 합성이다'라고 할 수 있습니다. 1.2.9절에서는 '열벡터'라는 언어를 사용하여 같은 내용을 한번 더 확인합니다.

1.2.5 행렬 연산의 성질

기본적인 성질
수 c, c', 벡터 x, 행렬 A, B, C에 대해 다음 성질이 성립합니다. 벡터나 행렬의 크기는 연산되도록 설정했습니다.

- (cA)x = c(Ax) = A(cx)

- (A + B)x = Ax + Bx

- A + B = B + A

- (A + B) + C = A + (B + C)

- (c + c')A = cA + c'A

- (cc')A = c(c'A)

- A(B + C) = AB + AC

- (A + B)C = AC + BC

- (cA)B = c(AB) = A(cB)

벡터도 행렬의 일종?
이미 잠깐 설명했듯이 n차원 벡터를 n * 1행려로 간주하여 덧셈, 정수배, 곱을 계산해도 결과는 같습니다.

1.2.6  행렬의 거듭제곱 = 사상의 반복
숫자에서와 같은 방식으로 정방행렬 A에 대해 다음과 같이 씁니다(정방이 아니면 처음부터 곱 AA가 정의되지 않습니다(크기가 맞지 않습니다.)).
사상으로 A2은 'A하고 한층 더 A한다', A3은 'A하고 A하고 A한다', An은 'A를 n번 반복 적용한다' 입니다. 거듭제곱은 가감승제보다도 먼저 계산하는 규칙입니다.


1.2.7 영행렬, 단위행렬, 대각행렬
특별한 행렬에는 이름을 붙여 둡시다.

- 영행렬
모든 성분이 0인 행렬을 영행렬이라 하고, 기호 O로 나타냅니다. 크기를 명시하고 싶을 때는 m*n 영행렬 Omn이나 n차 정방영행렬 On처럼 쓰기도 합니다.

영행렬이 나타내는 사상은 모든 것을 원점으로 이동시키는 사상입니다. 임의의 벡터 x에 대해 Ox = o이기 때문입니다.

- 단위행렬
정방행렬에서 대각선 위만 1이고 다른 것은 0인 행렬을 단위행렬이라고 하고, 기호 I로 나타냅니다. 크기를 명시하고 싶을때는 n차 단위행렬 In처럼 쓰기도 합니다.

'모든 성분이 1인 행렬'은 아니므로 주의합시다. 사상으로서의 의미를 보면 이해될 것입니다. 단위행렬이 나타내는 사상은 '아무것도 하지 않는' 사상입니다. 임의의 백터 x에 대해 Ix = x이므로 x를 원래 x 그래도 이동한다는 것을 알 수 있습니다. ㄱ

- 대각행렬
정방행렬의 대각선상의 값을 대각성분이라고 합니다.
대각성분 이외의 값은 비대각성분이라고 합니다.
비 대각성분이 모두 0인 행렬을 대각행렬이라 부릅니다.
거의 대부분 0인데 지면을 소비하면 아까우므로 다음과 같이 줄여서 씁니다. diag는 diagonal(대각선)의 줄임말입니다.

대각행렬이 나타내는 사상은 '축에 따르는 신축(늘고 줄음)이고, 대각성분이 각 축의 늘고 주는 배율이 됩니다. 따라서 대각성분 여하에 따라 공간이 변하는 모습도 다릅니다.

1.2.8 역행렬 = 역사상
다음은 A에 이동시킨 것을 원래대로 돌려 놓은 이야기입니다. 이 이야기는 2장에서 설명할 '결과에서 원인을 구한다'라는 주제와도 관련이 있습니다.

정의
정방행렬 A에 대해 그 역사상에 대응하는 행렬을 'A의 역행렬'이라고 하고, 기소 A-1이라 씁니다. 어떠한 x를 가져와도 'Ax = y 또는 A-1y = x'이고, 반대로 어떠한 y를 가져와도 A-1y = x또는 Ax =y'가 되는, 그런 행렬 A-1입니다. 대략 '이동점 y를 갖고 원래의 점 x를 구하다'라는 사상에 대응하는 행렬이 A-1입니다.
다르게 표현하면 A하고 A-1하면 원래대로 돌아가고, A-1하고 A해도 원래대로 돌아갑니다. 즉 다음과 같습니다.

A-1A = AA-1 = I

역행렬은 있을 수도, 없을 수도 있습니다. 직관적으로 말하면 '납작하게 눌리는' 경우는 역행렬이 존재하지 않습니다. 왜냐하면, '눌린다'는 것은 '서로 다른 두 점 x, x'가 A를 적용하면 같은 점 y = Ax = Ax'로 이동한다'라는 것이기 때문입니다. 그렇게 되면 '이동점이y'라고 주어져도 원래가 x였는지 x'였는지 구별이 안 됩니다. 즉, '이동점y를 들고 원래의 점 x를 답하는 사상'이라 만들수가 없습니다.

1.2.9 블록행렬
'큰 문제를 작은 부분 문제로 분할하는 것'은 복잡합에 대처하는 수단으로 효과가 있습니다. 행렬 연산에도 실은 그런 분할이 가능합니다.

정의와 성질
행렬의 종횡에 단락을 넣어 각 구역을 작은 행렬로 간주한 것을 블록행렬이라고 합니다.
쉬운 선형대수 책에는 그다지 실리지 않는 소재입니다만, 응용할 때 자주 사용하는 테크닉이므로 설명해 두겠습니다.
크기가 같은 블록 행렬 A=(Aij)와 B=(Bij), 수 c에 대해 다음 성질이 성립합니다.

행벡터, 열벡테
블록행렬의 특별한 경우로 다음과같이 한 방향으로만 작게 나누는 것도 생각해 볼 수 있습니다.
단락지어진 각 단편의 크기가 n*1이나 1*n'이므로 각 단락을 벡터라고 간주하는 것도 가능합니다. 그런 이유로 위 행렬처럼 나타났을 때 a1, a2...am을 'A의 열벡터'라고 하고,


2018년 2월 3일 토요일

1장 벡터,.행렬.행렬식 -'공간'에서 생각하자

1.1 벡터와 공간
1.2 행렬과 사상
1.3 행렬식과 확대율

0.1 절에서 설명했듯이 무엇가를 하려고 할 때 많은 수치를 묶은 데이터를 다루고 싶은 경우가 생길 것입니다. 그러한 데이터를 단순히 '수치의조합'으로 다루는 것이 아니라, '공간 안의 점'으로간주하여 직관을 활용하는 것이 이 책 전체의 주제입니다.

그 중심이 되는 개념인 '벡터'와 '행렬', 그리고 쓰만한 보조역인 '행렬식'을 이 장에서 설명합니다. 선형대수를 아무리 생각 없이 공부하면 무의식 중에 문자 배열에만 누이 가기 쉽습니다. 그래서는 직관을 활용할 수 없습니다. '공각'이라는 생걱을 잊지 마세요.

                 문자 배열(표면상)                                     의미
벡터           숫자를 일렬로 늘어 놓은  것                    화살표, 또는 공간 안의 점
행렬           숫자를 직사각형으로 늘어 놓은것         공간에서 공간으로의 직교 사상
행렬식       뭔가 귀찮은 계산                                       위의 사상에 따른 부피 확대율

이 장은 기술적인 측면에서 사칙연사을 정복하는 것이 목표입니다. 구체적으로 말하면 수치가 주어진 벡터.행렬뿐만 아니라 문자식에 대해서도 '실제의 모습'을 의식하여 계산할 수 있는 것이 중요합니다(1.2.16절 크기에 구애되라). 신호 처리나 데이터 분석 등 '선형대수를 도구로 사용하는 응용 분야'에서는 문자식을 제대로 다루지 않으면 따라갈 수 없기 때문입니다.

0장 왜 선형대수를 배워야 하는가?

0.1 공.간이라고 생각하면 직관이 먹힌다.

우리는 3차원 공간에 살고 있습니다. 3차원 세계의 일을 다루기 위해서는 '공간'을 잘 기술할 수 있는 용어가 필요합니다. 컴퓨터 그래픽스, 자동차 네비게이션, 게임 등이 대표적인 예일 것입니다. 선형대수의 무대가 되는 벡터 공간은 현실 공간의 성질을 특정 수준에서 추상화한 것입니다. 따라서 선형대수는 공간을 설명하는데 편리한 용어나 개념을 제공해 줍니다. 예를 들어 "2차원 평면에 3차원 물체를 어떻게 그릴 것인가"를 궁리한다면 "3차원 공간 중 이곳에 이런 물체가 있을 때 시점을 이런 식으로 이동.회전시키면 누에는 어떤 2차원 화상이 나타날까" 라는 문제가 발생합니다. 이러한 문제에서도 선형대수 용어는 기초적인 역할 을 담당합니다.

그러나 오직 현실 공간의 문제를 해결하기 위해 선형대수를 배우는 것은 아닙니다.
무슨 일을 해도 단일 수치가 아닌, 다수의 수치를 조합한 데이터를 다루고 싶은 경우가 나타날것입니다. 이 경우는 '공간'과 직접적인 관계가 없으므로일부러 공간을 의식하지 않고 다룰수 있습니다. 그렇지만 이 데이터를 '고차원 공간 내의 점'이라고 해석하면 '공간'에 대한 우리의 직관을 활용하는 것도 가능합니다.

우리는 3차원 공간만 인식할 수 있지만, 3차원 공간으로부터 유추하여 직관적으로 이해할 수 있는 '일반의 n차원에서 성립하는 현상'도 많습니다. 실제로 이러한 해석은 데이터 분석의수단으로 효과가 있습니다. 그리고 '공간'의 문제가 되면 선형대수가 나설 차례입니다. 주성분 분석이나 최소제곱법 등이 고전적이고 대표적인 예입니다. 이 책에서느닝러한 방향으로 응용도 염두에 두고 설명할 것입니다.

0.2 근사 수단으로 사용하기 편리하다

선형대수가 다루는 대상은 선형적, 즉 직선이나 평면처럼 '곧은 것'입니다. 곧은 대상이므로 다루기 쉽고, 예측하기 좋으며, 명쾌한 결과를 얻을수 있습니다.

"쉬운 문제만 다룬다는 것이낙? 쉬운 문제를 잘 풀 수 있다고 해도 전혀 훌륭하지 않아" 라고 생각해도 당연합니다. '곧은 것'만 다뤄서는 대단히 궁색하죠. 곡면을 그리고 싶을 수도 있고요. 그래프를 그리면 곡선이 되는 현상 또한 있을 것입니다.
그래서 선형대수는 유효합니다. 왜냐하면 대상의 대부분의 줌업(zoom up,확대)하면 거의다 곧기 때문입니다. 질이 나쁜 들쭉날쭉한 예를 제외하면 곡선이라도, 고면이라도, 충분히 확대해보면 곧게 보입니다. 이 경우 작은 범위를 생각하는 한, '곧다'라고 근사해도 그 나름대로 도움이 되는 결과를 얻을 수 있습니다. 곡면을 그릴 때도 '작은 평면의 조립'으로 근사 표현합니다. 그래프가 곡선이어도 단기 예측이라면 직선으로 근사하여 연장합니다. 이러한 방법이 어느 정도 유효한지는 무엇을 하고 싶은지에 따라 다릅니다. '우와, 조잡하다'라고 생각할지도 모르지만, 이와 비슷한 접근법은 의외로 많이 사용하고 있습니다. 진지하게 식을 세우기 어렵고 힘들 때, '우선 곧은 것으로 근사해보자'라는 방법은 공학에서는 상투적인 방법입니다. '이정도로 만족'인지 '다른 좋은 방법이 없다'인지는 한마디로 말하기 힘듭니다.
이 책을 읽으면서 '문제 선정이 너무 한정적이다. 이런 방법이 사용되는 경우는 거읭 ㅓㅂㅅ겠지'라고 느낀다면 이 이야기를 떠올려 주십시오.