django上传文件名相同_用于实现用python和django编写的图像分类的Keras UI

KerasUI是一种可视化工具,可以在图像分类中轻松训练模型,并允许将模型作为服务使用,只需调用API。

https://github.com/zeppaman/KerasUI 

主要特点:

  • 用oauth2验证

  • 允许完整的模型定制

  • 可以上传尚未训练的模型并通过API消费

  • 测试表格和视觉检查网络如何工作

  • 批量上传训练集

用法

  • 运行standalone.bat或sh standalone.bat(这将安装需求应用迁移并运行服务器,相同的脚本适用于UNIX和Windows)

  • 使用创建管理员用户 python manage.py createsuperuser

  • 导航到http://127.0.0.1:8000/

这需要python 3+,如果安装了多个版本,请根据(即pip3)更改脚本。

如何管理数据集

Keras UI允许将数据集项(图像)上载到Web应用程序中。您可以逐个执行此操作,也可以一次性添加包含许多图像的zip文件。它管理多个数据集,因此您可以将事物分开。加载图像后,可以单击“训练”按钮并运行训练过程。这将训练您定义的模型,而无需您进行任何交互。你将获得训练结果,如果你很挑剔,你可以转到日志文件,看看系统输出了什么

如何使用Web UI进行测试

为避免失眠,提供了一个简单的表格,可以上传图像并获得结果。

如何使用API UI或邮递员来测试API

在Web UI中看到的所有内容都可以使用API进行复制。

API使用情况

此应用程序使用oauth2来验证请求,因此需要的第一步是获取令牌。这是密码流的一个简单示例。请记住必须启用该应用程序(首次运行时不会默认创建)。

Assumingclient hUiSQJcR9ZrmWSecwh1gloi7pqGTOclss4GwIt1osecret ZuuLK21sQ2uZxk8dVG7k6pO474FBlM6DEQs7FQvDh28gdLtbCDJwFFi0YlTlLsbz9ddjUa7Lun6ifYwkfwyGMD95WsCuzibFWIMpsZHMA039RIv1mOsYUO5nK5ZVv1hB POST to http://127.0.0.1:8000/o/token/ Headers:Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWContent-Type: application/x-www-form-urlencoded Body:grant_type:passwordusername:adminpassword:admin2019!

回应是

{    "access_token": "h6WeZwYwqahFDqGDRr6mcToyAm3Eae",    "expires_in": 36000,    "token_type": "Bearer",    "scope": "read write",    "refresh_token": "eg97atDWMfqC1lYKW81XCvltj0sism"}

获取预测的API可以在json post或form post中使用。在json post中,图像以base64字符串形式发送。这种使用服务的双重方式非常有用,因为可以将其链接到表单或直接与wget或curl工具一起使用,也可以在应用程序中使用它。

POST http://127.0.0.1:8000/api/test/ Headers:Content-Type:application/jsonAuthorization:Bearer  Body{    "image":",    "dataset":1}

响应 

{    "result": ""}

教程

该项目是Codeproject上图像分类上下文的一部分。这里是技术部分的演练,解释它是如何构建的以及它是如何工作的。

项目堆栈:

  • python

  • django框架

  • keras,tensorflow,numpy

  • sqlite(或您喜欢的其他数据库)

使用的工具:

  • Visual Studio代码

  • 邮差

  • 一个Web浏览器

项目设置

该项目基于Django,因此首先要做的是使用CLI创建一个Django项目。这需要从pip安装Django。

django-admin startproject kerasui ' create the project

此命令将生成以下结构: 

kerasui/    manage.py    kerasui/        __init__.py        settings.py        urls.py        wsgi.py

这些文件是:

  • 外部kerasui / root目录只是项目的容器。内部mysite /目录是项目的实际Python包。它的名称是需要用来导入其中任何内容的Python包名称(例如mysite.urls)。

  • manage.py:一个命令行实用程序,允许以各种方式与此Django项目进行交互。可以在jango-admin和manage.py中阅读有关manage.py的所有详细信息。

  • __init__.py:一个空文件,告诉Python该目录应该被视为Python包。如果是Python初学者,请阅读官方Python文档中有关包的更多信息。

  • kerasui / settings.py:此Django项目的设置/配置。Django设置将告诉有关设置如何工作的所有信息。

  • kerasui / urls.py:此Django项目的URL声明; Django支持的站点的“目录”。可以在URL调度程序中阅读有关URL的更多信息。

  • kerasui / wsgi.py:与WSGI兼容的Web服务器的入口点,用于为项目提供服务。有关更多详细信息,请参阅如何使用WSGI进行部署。

运行

要检查是否一切正常,只需使用内置服务器运行django

python manage.py runserver

也可以使用setup visual studio代码来运行django /

这是django配置: 

{    // Use IntelliSense to learn about possible attributes.    // Hover to view descriptions of existing attributes.    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387    "version": "0.2.0",    "configurations": [        {            "name": "Python: Django",            "type": "python",            "request": "launch",            "program": "${workspaceFolder}\\kerasui\\manage.py",            "args": [                "runserver",                "--noreload",                "--nothreading"            ],            "django": true        }    ]}

设置配置

这里配置的基本部分告诉:

  • 使用oauth 2和会话认证使:常规Web用户登录并使用网站和休息沙箱,API用户获取令牌并查询API服务

  • 使用SQLite(可以更改为移动到任何其他数据库)

  • 添加所有Django模块(以及两个自定义:管理UI和API)

  • 启用cors

INSTALLED_APPS = [    'python_field',    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'oauth2_provider',    'corsheaders',    'rest_framework',      'management',    'api',] MIDDLEWARE = [    'django.middleware.security.SecurityMiddleware',    'django.contrib.sessions.middleware.SessionMiddleware',    'django.middleware.common.CommonMiddleware',   # 'django.middleware.csrf.CsrfViewMiddleware',    'django.contrib.auth.middleware.AuthenticationMiddleware',    'django.contrib.messages.middleware.MessageMiddleware',    'django.middleware.clickjacking.XFrameOptionsMiddleware',    'django.middleware.security.SecurityMiddleware',    'corsheaders.middleware.CorsMiddleware',] ROOT_URLCONF = 'kerasui.urls'  REST_FRAMEWORK = {    'DEFAULT_AUTHENTICATION_CLASSES': (        'rest_framework.authentication.SessionAuthentication',        'rest_framework.authentication.BasicAuthentication',        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',    ),    'DEFAULT_PERMISSION_CLASSES': (        'rest_framework.permissions.IsAuthenticated',    ),      'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',    'PAGE_SIZE': 10,} DATABASES = {    'default': {        'ENGINE': 'django.db.backends.sqlite3',        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),    }}

第一次运行

Django使用迁移系统从您定义的模型生成迁移文件。要应用迁移,只需运行migrate命令(makemigration即可从模型创建迁移文件)。

用户数据库开始为空,因此需要创建admin用户才能登录。这是通过createsuperadmin命令完成的

python manage.py migratepython manage.py createsuperuseradmin\admin2019!

它是如何构建的

该应用程序分为3个模块:

  • 管理部分: Web UI,模块和所有核心内容

  • 后台工作者:是一个可以在后台执行的Django命令,用于根据数据集训练模型

  • API:此部分公开API以从外部与应用程序交互。例如,这允许从第三方应用程序向数据集添加项目。此外,最常见的用法是发送图像并获得预测结果

管理

在Django上创建一个应用程序:

python manage.py startapp management

这将创建主文件。在这个模块中,使用的最多是模型和模型表示:

  • module.py:这里是所有具有现场规格的型号。通过这样的类定义,所有都被设置为对实体具有可用的CRUD

  • admin.py:此图层描述了如何使用表单显示和编辑数据。

数据模型非常简单。假设只想为每个数据集训练一个模型

  • DataSet:它包含模型,模型设置和数据集的名称。

  • DataSetItem:它包含数据集项,因此每行一个图像附加标签。

这里只是一个模型和模型表示的示例:

#from admin.pyclass DataSetForm( forms.ModelForm ):       process =forms.CharField( widget=forms.Textarea(attrs={'rows':40, 'cols':115}), initial=settings.PROCESS_TEMPLATE )    model_labels =forms.CharField(initial="[]")    class Meta:        model = DataSet        fields = ['name', 'process','epochs','batchSize','verbose','model_labels','model']        widgets = {          'process': forms.Textarea(attrs={'rows':20, 'cols':200}),          }    def train(modeladmin, request, queryset):       for dataset in queryset:        DataSetAdmin.train_async(dataset.id) class DataSetAdmin(admin.ModelAdmin):    list_display = ('name','epochs','batchSize','verbose','progress')    inlines = [      #  DataSetItemInline,    ]    form=DataSetForm    actions = [train]    change_list_template = "dataset_changelist.html"      @staticmethod    def train(datasetid):        call_command('train',datasetid)    @staticmethod    def train_async(datasetid):        t = threading.Thread(target=DataSetAdmin.train, args=(datasetid,))        t.setDaemon(True)        t.start()  admin.site.register(DataSet,DataSetAdmin) #from model.py class DataSet(models.Model):    name= models.CharField(max_length=200)    process = models.CharField(max_length=5000, default=settings.PROCESS_TEMPLATE)    model = models.ImageField(upload_to=path_model_name,max_length=300,db_column='modelPath',blank=True, null=True)    #weights = models.ImageField(upload_to=path_model_name,max_length=300,db_column='weightPath',blank=True, null=True)    batchSize = models.IntegerField(validators=[MaxValueValidator(100), MinValueValidator(1)],default=10)    epochs = models.IntegerField(validators=[MaxValueValidator(100), MinValueValidator(1)],default=10)    verbose = models.BooleanField(default=True)    progress = models.FloatField(default=0)        model_labels= models.CharField(max_length=200)    def __str__(self):        return self.name

Django采用代码优先方法,因此需要运行python manage.py makemigrations以生成将应用于数据库的迁移文件。

python manage.py makemigrations

背景工作者

要创建后台工作程序,需要一个模块来托管它,使用了管理模块。在其中需要创建一个management文件夹。其上的每个文件都可以python manage.py commandname通过API 运行或通过API 运行。

在例子中,通过常规的Django动作在后台进程中启动命令

这是相关部分:

class DataSetAdmin(admin.ModelAdmin):       actions = [train]      # ....        @staticmethod    def train(datasetid):        call_command('train',datasetid)    @staticmethod    def train_async(datasetid):        t = threading.Thread(target=DataSetAdmin.train, args=(datasetid,))        t.setDaemon(True)        t.start()

API

API是在一个单独的应用程序中创建的

python manage.py startapp API

基本上所有CRUD模型都可以通过API公开,但是需要指定如何序列化它

class DataSetItemSerializer(serializers.HyperlinkedModelSerializer):    image = Base64ImageField()    dataset=   serializers.PrimaryKeyRelatedField(many=False, read_only=True)    class Meta:        model = DataSetItem         # Fields to expose via API        fields = ('label', 'image', 'dataset')  class DataSetSerializer(serializers.HyperlinkedModelSerializer):         class Meta:        model = DataSet        fields = ('name', 'process')

还需要创建ViewSet模型和数据表示之间的映射:

class DataSetItemViewSet(viewsets.ModelViewSet):       queryset = DataSetItem.objects.all()    serializer_class = DataSetItemSerializer class DataSetViewSet(viewsets.ModelViewSet):       queryset = DataSet.objects.all()    serializer_class = DataSetSerializer

最后需要定义所有路由并将viwset映射到url。这足以将模型用作api

router = routers.DefaultRouter()router.register(r'users', views.UserViewSet)router.register(r'datasetitem', views.DataSetItemViewSet)router.register(r'dataset', views.DataSetViewSet)router.register(r'test', views.TestItemViewSet, basename='test') # Wire up our API using automatic URL routing.# Additionally, we include login URLs for the browsable API.urlpatterns = [    url(r'^', include(router.urls)),    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),] urlpatterns += staticfiles_urlpatterns()

训练

算法非常简单:

  1. 从数据集中获取所有图像

  2. 将它们标准化并添加到带标签的列表中

  3. 创建模型在数据集模型中的指定方式

  4. 训练它

这是查询数据集项和加载图像的代码段:

def load_data(self, datasetid):        self.stdout.write("loading images")        train_data = []                images = DataSetItem.objects.filter(dataset=datasetid)        labels = [x['label'] for x in  DataSetItem.objects.values('label').distinct()]              for image in images:            self.stdout.write("Loading {0}".format(image.image))            image_path = image.image.path            if "DS_Store" not in image_path:                           index=[x for x in range(len(labels)) if labels[x]==image.label]                label = to_categorical([index,],len(labels))                                img = Image.open(image_path)                img = img.convert('L')                img = img.resize((self.IMAGE_SIZE, self.IMAGE_SIZE), Image.ANTIALIAS)                train_data.append([np.array(img), np.array(label[0])])                    return train_data

看一眼:

labels = [x['label'] for x in  DataSetItem.objects.values('label').distinct()]label = to_categorical([index,],len(labels))

这为所有标签分配了一个顺序,即["CAT","DOGS"]然后to_categorical将位置索引转换为单热表示。用简单的话说,这使得CAT = [1,0]和DOG = [0,1]

训练模型

   model=Sequential()   exec(dataset.process)   model.add(Dense(len(labels), activation = 'softmax'))   model.fit(training_images, training_labels, batch_size=dataset.batchSize, epochs=dataset.epochs, verbose=dataset.verbose)

请注意,dataset.process是在Web管理员中输入的python模型定义,可以根据需要进行调整。最后一层添加到用户回调之外,以确保与数组大小匹配。

拟合方法只是使用所有数据运行训练(。

最后存储训练有素的模型:

datasetToSave=DataSet.objects.get(pk=datasetid)datasetToSave.progress=100datasetToSave.model_labels=json.dumps(labels)temp_file_name=str(uuid.uuid4())+'.h5'model.save(temp_file_name)datasetToSave.model.save('weights.h5',File(open(temp_file_name, mode='rb')))os.remove(temp_file_name)datasetToSave.save()

请注意还保存标签顺序beacuse必须与模型相同才能匹配one-hot约定。

预测

有一种常见的方法,给定样本和数据集,检索模型,加载模型并进行预测。这是一段代码:

def predict(image_path,datasetid):                    dataset=DataSet.objects.get(pk=datasetid)            modelpath=dataset.model.path            model=load_model(modelpath)            labels=json.loads(dataset.model_labels)                        img = Image.open(image_path)            img = img.convert('L')            img = img.resize((256, 256), Image.ANTIALIAS)             result= model.predict(np.array(img).reshape(-1,256,256, 1))            max=result[0]            idx=0            for i in range(1,len(result)):                if max                    max=result[i]                    idx=i              return labels[idx]

使用模型加载模型load_model(modelpath),标签来自数据库。模型预测输出作为值列表,选择较高的索引并用于检索在训练时分配给网络输出的正确标签。

3560ad4017a417e54071c7e2b7f3815d.png

关于图书

《深度学习之TensorFlow:入门、原理与进阶实战》和《Python带我起飞——入门、进阶、商业实战》两本图书是代码医生团队精心编著的 AI入门与提高的精品图书。配套资源丰富:配套视频、QQ读者群、实例源码、 配套论坛:http://bbs.aianaconda.com 。更多请见:https://www.aianaconda.com

ed1ddfdbb85e3ac2e986687ec0fdada8.png

918021f4471372b6a4194693ebc162c5.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值